<script setup lang="ts">
// eslint-disable
import { onMounted, onBeforeUnmount, ref, watch, computed } from 'vue'
// @ts-ignore
import EditorHeader from './EditorHeader.vue'
// @ts-ignore
import GMap from './MarsMap.vue'
import * as mars3d from 'mars3d'
// @ts-ignore
import { VueDraggableNext as draggable } from 'vue-draggable-next'
// @ts-ignore
import { message } from 'ant-design-vue'

// 设备与负载名称映射（参考 shangyun-dajiang/src/types/device.ts）
const DRONE_NAME_BY_ENUM: Record<number, string> = {
  67: 'M30',
  60: 'M300 RTK',
  11: 'Phantom 4',
  18: 'Phantom 4 Pro',
  59: 'Phantom 4 RTK',
  27: 'Phantom 4 Advanced',
  77: 'Mavic 3',
}
const PAYLOAD_NAME_BY_ENUM: Record<number, string> = {
  39: 'FPV',
  42: 'H20',
  43: 'H20T',
  61: 'H20N',
  50: 'P1',
  90742: 'L1',
  52: 'M30 Camera',
  53: 'M30T Camera',
  26: 'XT2',
  41: 'XTS',
  20: 'Z30',
  165: 'Dock Camera',
  66: 'Mavic 3E',
  67: 'Mavic 3T',
}
// 简化的上传占位实现
const upload = async (_wayline: any, _id?: any, _routeName?: any) => { /* no-op */ }

const Cesium = (mars3d as any).Cesium

// 基础占位图标（1x1透明像素）
const icon1px = ''
const homeIcon = icon1px
const QFD = icon1px
const ggtsg = icon1px

const props = defineProps<{ showLeft?: boolean }>()
const showLeftBox = computed(() => props.showLeft !== false)

// 路由占位
const waylineId = ref<string|number>('local')
const routeName = ref<string>('local')
const isFlightPanel = ref<boolean>(false)
const flightControl = ref<{ altitude: number; speed: number; turnMode: 'auto'|'waypoint'; hoverTime: number; missionMode: 'none'|'photo'; photoMode: 'time'|'distance'; timeInterval: number; distanceInterval: number }>({
  altitude: 100,
  speed: 10,
  turnMode: 'auto',
  hoverTime: 0,
  missionMode: 'none',
  photoMode: 'time',
  timeInterval: 3,
  distanceInterval: 30,
})

// 延后到全局高度定义后再注册（避免TDZ错误）

// 初始化示例/落地缓存读取
function createDefaultWayline() {
  return {
    updateTime: Date.now(),
    distance: 0,
    duration: 0,
    autoFlightSpeed: 5,
    flyToWaylineMode: 'pointToPoint',
    takeOffRefPoint: '',
    takeOffRefPointAGLHeight: 0,
    takeOffSecurityHeight: 30,
    globalHeight: 50,
    waylineCoordinateSysParam: { heightMode: 'EGM96' },
    globalWaypointHeadingParam: { waypointHeadingMode: 'followWayline' },
    gimbalPitchMode: 'manual',
    globalWaypointTurnMode: 'coordinateTurn',
    finishAction: 'goHome',
    payloadParam: { imageFormat: 'wide,zoom' },
    positionsArr: [
      [117.25, 31.84, 50],
      [117.26, 31.845, 50]
    ],
    Placemark: [
      {
        Point: { coordinates: '117.25,31.84' },
        index: '0',
        useGlobalHeight: '1',
        ellipsoidHeight: '0',
        height: '50',
        useGlobalSpeed: '1',
        waypointSpeed: '5',
        useGlobalHeadingParam: '1',
        waypointHeadingParam: {
          waypointHeadingMode: 'followWayline',
          waypointHeadingAngle: '0',
          waypointHeadingPathMode: 'followBadArc',
          waypointPoiPoint: '0,0,0',
          waypointHeadingPoiIndex: '0',
        },
        useGlobalTurnParam: '1',
        waypointTurnParam: { waypointTurnMode: 'coordinateTurn', waypointTurnDampingDist: '0.2' },
    useStraightLine: '1',
    gimbalPitchAngle: 0,
        actionGroup: [
          {
            actionGroupId: '0',
            actionGroupStartIndex: '0',
            actionGroupEndIndex: '0',
            actionGroupMode: 'sequence',
            actionTrigger: { actionTriggerType: 'reachPoint', actionTriggerParam: '' },
            action: [
              { actionId: '0', actionActuatorFunc: 'hover', actionActuatorFuncParam: { hoverTime: '2' } }
            ]
          }
        ]
      },
      {
        Point: { coordinates: '117.26,31.845' },
        index: '1',
        useGlobalHeight: '1',
        ellipsoidHeight: '0',
        height: '50',
        useGlobalSpeed: '1',
        waypointSpeed: '5',
        useGlobalHeadingParam: '1',
        waypointHeadingParam: {
          waypointHeadingMode: 'followWayline',
          waypointHeadingAngle: '0',
          waypointHeadingPathMode: 'followBadArc',
          waypointPoiPoint: '0,0,0',
          waypointHeadingPoiIndex: '0',
        },
        useGlobalTurnParam: '1',
        waypointTurnParam: { waypointTurnMode: 'coordinateTurn', waypointTurnDampingDist: '0.2' },
        useStraightLine: '1',
        gimbalPitchAngle: '0',
        actionGroup: []
      }
    ],
    droneInfo: { droneEnumValue: 1 },
    payloadInfo: { payloadEnumValue: 1 },
  }
}

const wayLineFrom = ref<any>(null)
const raw = localStorage.getItem('wayLine')
wayLineFrom.value = raw ? JSON.parse(raw) : createDefaultWayline()
if (!raw) localStorage.setItem('wayLine', JSON.stringify(wayLineFrom.value))

const droneName = computed(() => {
  const v = Number(wayLineFrom.value?.droneInfo?.droneEnumValue ?? 0)
  const sub = Number(wayLineFrom.value?.droneInfo?.droneSubEnumValue ?? -1)
  if (v === 67) return sub === 1 ? 'M30T' : 'M30' // M30/M30T 区分
  return DRONE_NAME_BY_ENUM[v] ?? 'Unknown'
})
const payloadName = computed(() => {
  const v = Number(wayLineFrom.value?.payloadInfo?.payloadEnumValue ?? 0)
  const sub = Number(wayLineFrom.value?.payloadInfo?.payloadSubEnumValue ?? -1)
  // 优先精确映射
  if (v in PAYLOAD_NAME_BY_ENUM) return PAYLOAD_NAME_BY_ENUM[v]
  // 针对M30系列相机根据sub做兜底
  if (v === 52) return 'M30 Camera'
  if (v === 53) return 'M30T Camera'
  // Mavic3系列相机
  if (v === 66) return 'Mavic 3E'
  if (v === 67) return 'Mavic 3T'
  return 'Unknown'
})

// 将结束标记自动插入（与参考实现保持）
try {
  wayLineFrom.value.Placemark.forEach((point: any) => {
    point.actionGroup.forEach((actionGroup: any) => {
      if (actionGroup.actionGroupEndIndex*1 - actionGroup.actionGroupStartIndex*1 > 0) {
        const arr = { actionActuatorFunc: 'actionGroupEndIndex', actionGroupStartIndex: actionGroup.actionGroupStartIndex, actionGroupEndIndex: actionGroup.actionGroupEndIndex }
        const endActionGroup = wayLineFrom.value.Placemark[actionGroup.actionGroupEndIndex-1].actionGroup
        let flag = false
        for (let i=0;i<endActionGroup.length;i++) {
          for (let x=0;x<endActionGroup[i].action.length;x++) {
            if (endActionGroup[i].action[x].actionActuatorFunc === 'takePhoto') { endActionGroup[i].action.splice(x,0,arr); flag = true; break }
            else if (endActionGroup[i].action[x].actionActuatorFunc === 'actionGroupEndIndex') { break }
          }
          if (flag) break
        }
      }
    })
  })
} catch {}

const isChanged = ref(false)
watch(() => wayLineFrom.value, () => {
  const o = localStorage.getItem('wayLine')
  if (o && JSON.stringify(wayLineFrom.value) === JSON.stringify(JSON.parse(o))) {
    isChanged.value = false
    window.removeEventListener('beforeunload', beforeunloadHandler as any)
  } else {
    isChanged.value = true
    window.addEventListener('beforeunload', beforeunloadHandler as any)
  }
}, { deep: true })

function beforeunloadHandler(e: any) {
  e = e || window.event
  if (e) e.returnValue = '您是否确认离开此页面-您输入的数据可能不会被保存'
  return '您是否确认离开此页面-您输入的数据可能不会被保存'
}

const Placemark = ref<any>({
  Point: { coordinates: '0,0' },
  index: 0,
  useGlobalHeight: '1',
  height: 0,
  useGlobalSpeed: '1',
  waypointSpeed: 5,
  useGlobalHeadingParam: '1',
  waypointHeadingParam: { waypointHeadingMode: 'followWayline', waypointHeadingAngle: 0, waypointHeadingPathMode: 'followBadArc', waypointPoiPoint: '0,0,0', waypointHeadingPoiIndex: 0 },
  useGlobalTurnParam: '1',
  waypointTurnParam: { waypointTurnMode: 'coordinateTurn', waypointTurnDampingDist: '0.2' },
  useStraightLine: '1',
  gimbalPitchAngle: 0,
  actionGroup: []
})
Placemark.value = wayLineFrom.value.Placemark[0] || Placemark.value
const PlacemarkNum = ref<number>(0)

const distance = ref<number>(wayLineFrom.value.distance * 1)
const duration = ref<number>(wayLineFrom.value.duration * 1)

const orientedPhotoMode = ref(true)
const flyToWaylineMode = ref(wayLineFrom.value.flyToWaylineMode !== 'safely')

const qfdIsShow = ref<boolean>(false)
const takeOffRefPointLon = ref<number>()
const takeOffRefPointLat = ref<number>()
const takeOffRefPointAGLHeight = ref<number>(0)
const takeOffRefPointH = ref<number>(wayLineFrom.value.takeOffRefPointAGLHeight * 1)
const takeOffSecurityHeight = ref<number>(wayLineFrom.value.takeOffSecurityHeight * 1)
const heightMode = ref<string>(wayLineFrom.value.waylineCoordinateSysParam.heightMode)
const heightModecopy = ref<string>(heightMode.value)
const heightAGL = ref<number>(wayLineFrom.value.globalHeight * 1)
const heightALT = ref<number>(wayLineFrom.value.globalHeight * 1)
const globalHeight = ref<number>(wayLineFrom.value.globalHeight * 1)

const heightWGS84 = ref<number>(wayLineFrom.value.globalHeight * 1)

const waypointHeadingMode = ref<string>(wayLineFrom.value.globalWaypointHeadingParam.waypointHeadingMode)
const gimbalPitchMode = ref<string>(wayLineFrom.value.gimbalPitchMode)
const globalWaypointTurnMode = ref<string>(wayLineFrom.value.globalWaypointTurnMode)
const finishAction = ref<string>(wayLineFrom.value.finishAction)

const showpointInfo = ref<boolean>(false)
const wayLinePointName = ref<string>('')
const pointLon = ref<number>()
const pointLat = ref<number>()
const pointH = ref<number>()
const height = ref<number>(0)
const addActions = ref<boolean>(false)
const orientedFileSuffixEdit = ref<boolean>(false)
const orientedFileSuffix = ref<string>()
const orientedActionId = ref<string>()
const detGraphicFlag = ref<boolean>(false)

const zoom = ref<boolean>(wayLineFrom.value.payloadParam.imageFormat.indexOf('zoom')!==-1)
const wide = ref<boolean>(wayLineFrom.value.payloadParam.imageFormat.indexOf('wide')!==-1)

function changeImageFormat() {
  let imageFormat = ''
  imageFormat = [wide.value?'wide':'', zoom.value?'zoom':''].filter(Boolean).join(',')
  wayLineFrom.value.payloadParam.imageFormat = imageFormat
  wayLineFrom.value.Placemark.forEach((placemark: any) => {
    placemark.actionGroup.forEach((actionGroup: any) => {
      actionGroup.action.forEach((action: any) => {
        if ((['orientedShoot','takePhoto','startRecord'].includes(action.actionActuatorFunc)) && action.actionActuatorFuncParam.useGlobalPayloadLensIndex == 1) {
          action.actionActuatorFuncParam.payloadLensIndex = imageFormat
          action.actionActuatorFuncParam.gshxW = wide.value
          action.actionActuatorFuncParam.gshxZ = zoom.value
        }
      })
    })
  })
}

onMounted(() => {
  // 允许编辑
  ;(window as any).QFDLayer?.setOptions?.({ hasEdit: true })
  ;(window as any).graphicLayer?.setOptions?.({ hasEdit: true })

  ;(window as any).QFDLayer?.on?.(mars3d.EventType.editMouseMove, (event: any) => {
    takeOffRefPointLon.value = event.graphic.getCoordinate()[0]
    takeOffRefPointLat.value = event.graphic.getCoordinate()[1]
    takeOffRefPointAGLHeight.value = event.graphic.getCoordinate()[2]
    resetQFD('QFD')
  })
  ;(window as any).graphicLayer?.on?.(mars3d.EventType.editStart, (event: any) => {
    console.log('event', event)
    wayLinePointName.value = event.graphic.name
    showpointInfo.value = true
    pointLon.value = event.graphic.getCoordinate()[0]
    pointLat.value = event.graphic.getCoordinate()[1]
    pointH.value = event.graphic.getCoordinate()[2]
    PlacemarkNum.value = event.graphic.options.attr.index * 1
    Placemark.value = wayLineFrom.value.Placemark[PlacemarkNum.value]
  })
  ;(window as any).graphicLayer?.on?.(mars3d.EventType.editStop, (event: any) => {
    Placemark.value.Point.coordinates = `${wayLineFrom.value.positionsArr[PlacemarkNum.value][0]},${wayLineFrom.value.positionsArr[PlacemarkNum.value][1]}`
    wayLineFrom.value.Placemark[PlacemarkNum.value] = Placemark.value
    showpointInfo.value = false
    addActions.value = false
  })
  ;(window as any).graphicLayer?.on?.(mars3d.EventType.editMovePoint, (event: any) => {
    pointLon.value = event.graphic.getCoordinate()[0]
    pointLat.value = event.graphic.getCoordinate()[1]
    pointH.value = event.graphic.getCoordinate()[2]
    const graphic = (window as any).graphicLayer.graphics[(window as any).graphicLayer.graphics.length - 1]
    distance.value = graphic.distance
  })
  selectRoute()
  // 初始进入时，如果未提供独立的WGS84高度，使用globalHeight显示
  try {
    const savedWgs = Number((wayLineFrom.value as any).heightWGS84)
    heightWGS84.value = Number.isFinite(savedWgs) ? savedWgs : Number(wayLineFrom.value.globalHeight || 0)
  } catch { heightWGS84.value = Number(wayLineFrom.value.globalHeight || 0) }

  ;(window as any).graphicLayer?.on?.(mars3d.EventType.editMouseMove, (event: any) => {
    const position = event.graphic.getCoordinate()
    pointLon.value = position[0]
    pointLat.value = position[1]
    resetQFD('HXD')
    if (((window as any).QFDLayer?.graphics?.length ?? 0) >= 1) resetQFD('ISResetAllHXD')
  })

})

// 现在 globalHeight 已声明完成，再注册双向同步的观察者，避免TDZ
watch(() => flightControl.value.altitude, (v) => {
  const n = Number(v) || 0
  if (globalHeight.value !== n) {
    globalHeight.value = n
    try { wayLineFrom.value.globalHeight = n } catch {}
    if (heightMode.value === 'EGM96') {
      try { resetQFD('AllHXD') } catch {}
    }
  }
})
watch(() => globalHeight.value, (v) => {
  const n = Number(v) || 0
  if (flightControl.value.altitude !== n) {
    flightControl.value.altitude = n
  }
}, { immediate: true })

// 同步：飞控参数中的“飞行速度” <-> 大疆参数中的“飞行速度(autoFlightSpeed)”
watch(() => flightControl.value.speed, (v) => {
  const n = Number(v) || 0
  if (wayLineFrom.value.autoFlightSpeed !== n) {
    wayLineFrom.value.autoFlightSpeed = n
    try { changeAutoFlightSpeed() } catch {}
  }
})
watch(() => wayLineFrom.value.autoFlightSpeed, (v) => {
  const n = Number(v) || 0
  if (flightControl.value.speed !== n) {
    flightControl.value.speed = n
  }
}, { immediate: true })

// 允许外部列表通过事件触发重新加载本地航线（ImportList.vue -> wayline:openEditor）
function applyWayline(fromStorage: any) {
  console.log('[applyWayline] 开始应用航线数据')
  if (!fromStorage) {
    console.error('[applyWayline] 传入数据为空')
    return
  }
  
  console.log('[applyWayline] 原始数据结构:', {
    hasPositionsArr: !!fromStorage.positionsArr,
    hasPlacemark: !!fromStorage.Placemark,
    positionsCount: fromStorage.positionsArr?.length,
    placemarkCount: fromStorage.Placemark?.length
  })
  
  wayLineFrom.value = fromStorage
  console.log('[applyWayline] wayLineFrom.value 已更新:', wayLineFrom.value) 
  
  // 同步基础派生状态
  distance.value = Number(wayLineFrom.value.distance || 0)
  duration.value = Number(wayLineFrom.value.duration || 0)
  console.log('[applyWayline] 距离和时长:', { distance: distance.value, duration: duration.value })
  flyToWaylineMode.value = wayLineFrom.value.flyToWaylineMode !== 'safely'
  takeOffRefPointH.value = Number(wayLineFrom.value.takeOffRefPointAGLHeight || 0)
  takeOffSecurityHeight.value = Number(wayLineFrom.value.takeOffSecurityHeight || 0)
  const mode = wayLineFrom.value?.waylineCoordinateSysParam?.heightMode || 'EGM96'
  heightMode.value = mode
  heightModecopy.value = mode
  const gh = Number(wayLineFrom.value.globalHeight || 0)
  if (mode === 'aboveGroundLevel') {
    // 相对地面：全局高度代表AGL
    heightAGL.value = gh
    heightALT.value = gh
    globalHeight.value = gh
  } else if (mode === 'relativeToStartPoint') {
    // 相对起飞点：全局高度代表ALT
    heightALT.value = gh
    heightAGL.value = gh
    globalHeight.value = gh
  } else {
    // EGM96：全局高度为海拔
    globalHeight.value = gh
    heightALT.value = gh
    heightAGL.value = gh
  }
  // 椭球高度(WGS84)在地图绘制后再根据当前点估算
  heightWGS84.value = globalHeight.value
  // 模式/参数类字段
  waypointHeadingMode.value = wayLineFrom.value?.globalWaypointHeadingParam?.waypointHeadingMode || 'followWayline'
  gimbalPitchMode.value = wayLineFrom.value?.gimbalPitchMode || 'manual'
  globalWaypointTurnMode.value = wayLineFrom.value?.globalWaypointTurnMode || 'coordinateTurn'
  finishAction.value = wayLineFrom.value?.finishAction || 'goHome'
  // 负载格式
  try {
    const fmt = String(wayLineFrom.value?.payloadParam?.imageFormat || '')
    zoom.value = fmt.includes('zoom')
    wide.value = fmt.includes('wide')
  } catch {}
  // 同步：飞控参数中的“飞行高度” <-> 大疆参数中的“海拔高度(EGM96)”
  try {
    if (Number.isFinite(Number(globalHeight.value))) {
      flightControl.value.altitude = Number(globalHeight.value)
    }
  } catch {}
  // 航点面板初始化
  PlacemarkNum.value = 0
  if (Array.isArray(wayLineFrom.value?.Placemark) && wayLineFrom.value.Placemark.length > 0) {
    Placemark.value = wayLineFrom.value.Placemark[0]
  }
  // 当前点坐标
  try {
    const p0 = Array.isArray(wayLineFrom.value?.positionsArr) ? wayLineFrom.value.positionsArr[0] : undefined
    if (Array.isArray(p0) && p0.length >= 2) {
      pointLon.value = Number(p0[0])
      pointLat.value = Number(p0[1])
      pointH.value = Number(p0[2] || 0)
    }
  } catch {}
  // 起飞点坐标
  try {
    if (typeof wayLineFrom.value?.takeOffRefPoint === 'string' && wayLineFrom.value.takeOffRefPoint.includes(',')) {
      const parts = wayLineFrom.value.takeOffRefPoint.split(',')
      takeOffRefPointLon.value = Number(parts[1])
      takeOffRefPointLat.value = Number(parts[0])
      takeOffRefPointAGLHeight.value = Number(parts[2] || 0)
    }
  } catch {}
  // 尝试同步id/名称
  try {
    if (wayLineFrom.value?.meta?.id || wayLineFrom.value?.id) waylineId.value = wayLineFrom.value?.meta?.id ?? wayLineFrom.value?.id
    if (wayLineFrom.value?.name) routeName.value = wayLineFrom.value.name
  } catch {}
}

async function handleOpenEditor(e?: any) {
  try {
    console.log('[WaylineEditor] 接收到事件:', e)
    console.log('[WaylineEditor] 事件详情:', e?.detail)
    
    const payload = e?.detail?.wayline
    console.log('[WaylineEditor] 提取的航线数据:', payload)
    
    if (!payload) {
      console.error('[WaylineEditor] 航线数据为空，无法打开编辑器')
      return
    }
    
    console.log('[WaylineEditor] 调用 applyWayline 应用航线数据')
    applyWayline(payload)
    
    console.log('[WaylineEditor] 重绘地图')
    // 重绘地图
    await selectRoute()
    
    // 根据来源选择默认面板：kmz→大疆参数，kml→飞控参数（由ImportList传入panel/isFlightPanel）
    try {
      const panel = e?.detail?.panel
      const flag = e?.detail?.isFlightPanel
      console.log('[WaylineEditor] 面板类型判断:', { panel, flag })
      
      if (typeof flag === 'boolean') {
        isFlightPanel.value = flag
      } else if (panel === 'flight') {
        isFlightPanel.value = true
      } else if (panel === 'dji') {
        isFlightPanel.value = false
      }
      console.log('[WaylineEditor] 最终面板类型:', isFlightPanel.value ? '飞控参数' : '大疆参数')
    } catch (err) {
      console.error('[WaylineEditor] 设置面板类型失败:', err)
    }
    
    // 根据数据或回退，设置椭球高度显示
    try {
      const savedWgs = Number((wayLineFrom.value as any).heightWGS84)
      heightWGS84.value = Number.isFinite(savedWgs) ? savedWgs : Number(wayLineFrom.value.globalHeight || 0)
      console.log('[WaylineEditor] 设置椭球高度:', heightWGS84.value)
    } catch { 
      heightWGS84.value = Number(wayLineFrom.value.globalHeight || 0) 
      console.log('[WaylineEditor] 使用默认椭球高度:', heightWGS84.value)
    }
    
    // 打开后视为未修改状态
    isChanged.value = false
    window.removeEventListener('beforeunload', beforeunloadHandler as any)
    
    console.log('[WaylineEditor] 编辑器打开完成')
  } catch (err) {
    console.error('[WaylineEditor] 打开编辑器失败:', err)
  }
}

onMounted(() => {
  window.addEventListener('wayline:openEditor', handleOpenEditor)
})

onBeforeUnmount(() => {
  window.removeEventListener('wayline:openEditor', handleOpenEditor)
})

function goback() { /* 在桌面端无路由，留空 */ }

function deleteCurrent() {
  try {
    const glayer: any = (window as any).graphicLayer
    const qlayer: any = (window as any).QFDLayer
    try { glayer?.clear?.() } catch {}
    try { qlayer?.clear?.() } catch {}
    // 清空当前编辑缓存
    localStorage.removeItem('wayLine')
    // 重置本地编辑状态
    wayLineFrom.value = createDefaultWayline()
    Placemark.value = wayLineFrom.value.Placemark[0]
    PlacemarkNum.value = 0
    showpointInfo.value = false
    isChanged.value = false
  } catch {}
}

async function save() {
  // 修复间隔拍照结束位置（简化版保持原逻辑）
  for (let i=0;i<wayLineFrom.value.Placemark.length;i++) {
    wayLineFrom.value.Placemark[i].actionGroup.forEach((actionGroup: any) => {
      if (['multipleTiming','multipleDistance'].includes(actionGroup.actionTrigger.actionTriggerType)) {
        for (let m=i+1;m<wayLineFrom.value.Placemark.length;m++) {
          wayLineFrom.value.Placemark[m].actionGroup.forEach((actionGroup2: any, actionGroup2Index: number) => {
            actionGroup2.action.forEach((action: any, actionIndex: number) => {
              if (action.actionActuatorFunc === 'takePhoto') {
                let checkTakePhotoFlag = false
                for (let x=i+1;x<=m;x++) {
                  wayLineFrom.value.Placemark[x].actionGroup.forEach((checkTakePhoto: any) => {
                    for (let n=0;n<checkTakePhoto.action.length;n++) {
                      if (checkTakePhoto.action[n].actionActuatorFunc === 'actionGroupEndIndex') {
                        checkTakePhotoFlag = true
                        checkTakePhoto.action[n].actionGroupStartIndex = i
                        checkTakePhoto.action[n].actionGroupEndIndex = x
                        break
                      }
                    }
                  })
                  if (checkTakePhotoFlag) break
                }
                if (!checkTakePhotoFlag) {
                  actionGroup2.action.splice(actionIndex,1)
                  if (actionGroup2.action.length === 0) wayLineFrom.value.Placemark[m].actionGroup.splice(actionGroup2Index,1)
                }
              }
            })
          })
        }
      }
    })
  }
  wayLineFrom.value.updateTime = Date.now()
  localStorage.setItem('wayLine', JSON.stringify(wayLineFrom.value))
  isChanged.value = false
  await upload(wayLineFrom.value, waylineId.value, routeName.value)
  window.removeEventListener('beforeunload', beforeunloadHandler as any)
  message.success('已保存')
}

async function selectRoute() {
  const glayer: any = (window as any).graphicLayer
  if (!glayer) return
  glayer.clear()
  glayer.setOptions?.({ id: waylineId.value })
  const positionsArr: number[][] = []

  const getQFDGroundHeight = wayLineFrom.value.takeOffRefPoint
    ? await mars3d.PointUtil.getSurfaceHeight((window as any).map.scene, [wayLineFrom.value.takeOffRefPoint.split(',')[1]*1, wayLineFrom.value.takeOffRefPoint.split(',')[0]*1] as any).then((r:any)=>r.height)
    : 0

  const tasks = wayLineFrom.value.Placemark.map(async (_point: any, index: number) => {
    const getGroundHeight = await mars3d.PointUtil.getSurfaceHeight((window as any).map.scene, [wayLineFrom.value.positionsArr[index][0], wayLineFrom.value.positionsArr[index][1]] as any).then((r:any)=>r.height)
    const positionGround = [wayLineFrom.value.positionsArr[index][0], wayLineFrom.value.positionsArr[index][1], getGroundHeight]
    const positionPath = [wayLineFrom.value.positionsArr[index][0], wayLineFrom.value.positionsArr[index][1], wayLineFrom.value.positionsArr[index][2]]
    positionsArr.push(positionPath as any)
    createPoint(positionGround as any, positionPath as any, index)
  })
  await Promise.all(tasks)
  resetRoad(positionsArr as any)

  const qfdLayer: any = (window as any).QFDLayer
  if ((qfdLayer?.graphics?.length ?? 0) >= 1) {
    qfdIsShow.value = true
    takeOffRefPointH.value = wayLineFrom.value.takeOffRefPointAGLHeight
  } else if (wayLineFrom.value.takeOffRefPoint !== '') {
    qfdIsShow.value = false
    const positionGround = [wayLineFrom.value.takeOffRefPoint.split(',')[1] * 1, wayLineFrom.value.takeOffRefPoint.split(',')[0] * 1, getQFDGroundHeight]
    takeOffRefPointAGLHeight.value = getQFDGroundHeight
    arrangeQFDPositions(positionGround as any)
  }
}

function resetRoad(positionsArr: any[]) {
  const glayer: any = (window as any).graphicLayer
  if (!glayer) return
  const turn = wayLineFrom.value.globalWaypointTurnMode
  const Base = (turn === 'toPointAndStopWithContinuityCurvature' || turn === 'toPointAndPassWithContinuityCurvature') ? mars3d.graphic.CurveEntity : mars3d.graphic.PolylineEntity
  const line = new Base({
    positions: positionsArr,
    name: 'road',
    hasEdit: false,
    hasHeightEdit: false,
    style: {
      width: 4,
      materialType: mars3d.MaterialType.LineFlow,
      materialOptions: { image: homeIcon, color: '#1a9850', mixt: true, speed: 20, repeat: new Cesium.Cartesian2(5, 1) }
    },
  })
  glayer.addGraphic(line)
  line.flyTo?.()
  distance.value = line.distance
}

function createPoint(positionGround: number[], positionPath: number[], index: number) {
  const glayer: any = (window as any).graphicLayer
  const path = new mars3d.graphic.BillboardEntity({ position: positionPath, hasEdit: false, style: { image: ggtsg, pixelSize: 10, color: '#000', clampToGround: false } })
  path.addTo(glayer)
  const ground = new mars3d.graphic.PointEntity({ position: positionGround, attr: { name: '航点' + (index + 1), index }, style: { color: '#000', pixelSize: 10, clampToGround: true, highlight: { type: mars3d.EventType.click, pixelSize: 15, color: '#ff0000' } } })
  ground.addTo(glayer)
  const line = new mars3d.graphic.PolylineEntity({ positions: [positionGround, positionPath], hasEdit: false, hasHeightEdit: false, maxPointNum: 2, style: { color: '#000', width: 1, material: mars3d.MaterialUtil.createMaterialProperty(mars3d.MaterialType.PolylineDash, { color: '#000' }) } })
  line.addTo(glayer)
}

function setQFD() {
  const qlayer: any = (window as any).QFDLayer
  qlayer.startDraw({ type: 'billboard', style: { image: QFD, pixelSize: 10 }, success: (graphic: any) => { const positionGround = graphic.getCoordinate(); arrangeQFDPositions(positionGround as any) } })
}

function arrangeQFDPositions(positionGround: any[]) {
  const positionPath = [...positionGround]
  const qlayer: any = (window as any).QFDLayer
  qlayer.clear()
  positionPath[2] = positionPath[2] + takeOffRefPointH.value
  const positionTop = [...positionPath]
  const point3 = [...positionPath]
  point3[2] = point3[2] + takeOffSecurityHeight.value
  const point5 = (window as any).graphicLayer.graphics[0].getCoordinate()
  createQFDGroup(positionGround as any, positionPath as any)

  let line: any[]
  if (takeOffSecurityHeight.value + takeOffRefPointH.value + takeOffRefPointAGLHeight.value > (window as any).graphicLayer.graphics[0].getCoordinate()[2]) {
    positionTop[2] = takeOffSecurityHeight.value + takeOffRefPointH.value + takeOffRefPointAGLHeight.value
    const point4 = (window as any).graphicLayer.graphics[0].getCoordinate()
    point4[2] = takeOffSecurityHeight.value + takeOffRefPointH.value + takeOffRefPointAGLHeight.value
    line = flyToWaylineMode.value ? [positionPath, point3, positionTop, point5] : [positionPath, point3, positionTop, point4, point5]
    createWayQFD2HXD(line)
  } else {
    positionTop[2] = (window as any).graphicLayer.graphics[0].getCoordinate()[2]
    line = flyToWaylineMode.value ? [positionPath, point3, point5] : [positionPath, point3, positionTop, point5]
    createWayQFD2HXD(line)
  }

  takeOffRefPointLon.value = positionGround[0]
  takeOffRefPointLat.value = positionGround[1]
  takeOffRefPointAGLHeight.value = positionGround[2]
  qfdIsShow.value = true
  wayLineFrom.value.takeOffRefPoint = `${positionGround[1]},${positionGround[0]},${positionGround[2]}`
  wayLineFrom.value.takeOffRefPointAGLHeight = takeOffRefPointH.value
}

function createQFDGroup(positionGround: any[], positionPath: any[]) {
  const qlayer: any = (window as any).QFDLayer
  const billboard = new mars3d.graphic.BillboardEntity({ position: positionPath, hasEdit: false, style: { image: QFD, pixelSize: 10 } })
  billboard.addTo(qlayer)
  const ground = new mars3d.graphic.PointEntity({ position: positionGround, style: { color: '#000', pixelSize: 10, clampToGround: true, highlight: { type: mars3d.EventType.click, pixelSize: 15, color: '#ff0000' } } })
  ground.addTo(qlayer)
  const line = new mars3d.graphic.PolylineEntity({ positions: [positionGround, positionPath], hasEdit: false, hasHeightEdit: false, maxPointNum: 2, style: { color: '#000', width: 1, material: mars3d.MaterialUtil.createMaterialProperty(mars3d.MaterialType.PolylineDash, { color: '#000' }) } })
  line.addTo(qlayer)
}

function createWayQFD2HXD(line: any[]) {
  const qlayer: any = (window as any).QFDLayer
  const road = new mars3d.graphic.PolylineEntity({ positions: line as any, name: 'QFroad', hasEdit: false, hasHeightEdit: false, style: { width: 4, materialType: mars3d.MaterialType.LineFlow, materialOptions: { image: homeIcon, color: '#1a9850', mixt: true, speed: 20, repeat: new Cesium.Cartesian2(5, 1) } } })
  road.addTo(qlayer)
}

function delQFD() {
  ;(window as any).QFDLayer?.clear?.()
  qfdIsShow.value = false
  wayLineFrom.value.takeOffRefPoint = ''
  wayLineFrom.value.takeOffRefPointAGLHeight = 0
}

function positionUp(control: string) { control==='QFD' ? takeOffRefPointLon.value = +(Number(takeOffRefPointLon.value)+0.000001).toFixed(9) : pointLon.value = +(Number(pointLon.value)+0.000001).toFixed(9); resetQFD(control) }
function positionDown(control: string) { control==='QFD' ? takeOffRefPointLon.value = +(Number(takeOffRefPointLon.value)-0.000001).toFixed(9) : pointLon.value = +(Number(pointLon.value)-0.000001).toFixed(9); resetQFD(control) }
function positionRight(control: string) { control==='QFD' ? takeOffRefPointLat.value = +(Number(takeOffRefPointLat.value)+0.000001).toFixed(9) : pointLat.value = +(Number(pointLat.value)+0.000001).toFixed(9); resetQFD(control) }
function positionLeft(control: string) { control==='QFD' ? takeOffRefPointLat.value = +(Number(takeOffRefPointLat.value)-0.000001).toFixed(9) : pointLat.value = +(Number(pointLat.value)-0.000001).toFixed(9); resetQFD(control) }

async function resetQFD(control: string) {
  const glayer: any = (window as any).graphicLayer
  const qlayer: any = (window as any).QFDLayer
  if (!glayer) return
  if (control === 'QFD' || control === 'ISResetAllHXD') {
    takeOffRefPointAGLHeight.value = mars3d.PointUtil.getHeight((window as any).map.scene, [takeOffRefPointLon.value as any, takeOffRefPointLat.value as any] as any)
    const billboardPosition = [takeOffRefPointLon.value, takeOffRefPointLat.value, Number(takeOffRefPointAGLHeight.value) + Number(takeOffRefPointH.value)]
    const groundPosition = [takeOffRefPointLon.value, takeOffRefPointLat.value, takeOffRefPointAGLHeight.value]
    const linePosition = [groundPosition, billboardPosition]
    const point3 = [...billboardPosition]
    point3[2] = Number(point3[2]) + Number(takeOffSecurityHeight.value)
    const point5 = glayer.graphics[0].getCoordinate()
    const positionTop = [...billboardPosition]
    let line: any[] = []
    if (Number(takeOffSecurityHeight.value) + Number(takeOffRefPointH.value) + Number(takeOffRefPointAGLHeight.value) > glayer.graphics[0].getCoordinate()[2]) {
      positionTop[2] = Number(takeOffSecurityHeight.value) + Number(takeOffRefPointH.value) + Number(takeOffRefPointAGLHeight.value)
      const point4 = glayer.graphics[0].getCoordinate(); point4[2] = positionTop[2]
      line = flyToWaylineMode.value ? [billboardPosition, point3, positionTop, point5] : [billboardPosition, point3, positionTop, point4, point5]
    } else {
      positionTop[2] = glayer.graphics[0].getCoordinate()[2]
      line = flyToWaylineMode.value ? [billboardPosition, point3, point5] : [billboardPosition, point3, positionTop, point5]
    }
    qlayer.graphics[0].setCallbackPosition(billboardPosition)
    qlayer.graphics[1].setCallbackPosition(groundPosition as any)
    qlayer.graphics[2].setCallbackPositions(linePosition as any)
    qlayer.graphics[3]?.remove?.()
    createWayQFD2HXD(line)
  } else if (control === 'HXD' || control === 'MoveHXD') {
    const index = PlacemarkNum.value
    const groundHeight = mars3d.PointUtil.getHeight((window as any).map.scene, [wayLineFrom.value.positionsArr[index][0] as any, wayLineFrom.value.positionsArr[index][1] as any] as any)
    const groundPosition = [pointLon.value, pointLat.value, groundHeight]
    if (Placemark.value.useGlobalHeight == '1') {
      if (heightMode.value === 'aboveGroundLevel') { Placemark.value.height = heightAGL.value; wayLineFrom.value.positionsArr[index][2] = groundHeight + heightAGL.value }
      else if (heightMode.value === 'relativeToStartPoint') { Placemark.value.height = heightALT.value; wayLineFrom.value.positionsArr[index][2] = Number(takeOffRefPointAGLHeight.value) + Number(heightALT.value) + Number(takeOffRefPointH.value) }
      else if (heightMode.value === 'EGM96') { Placemark.value.height = globalHeight.value; wayLineFrom.value.positionsArr[index][2] = globalHeight.value }
    } else {
      if (heightMode.value === 'aboveGroundLevel') { control==='MoveHXD' ? wayLineFrom.value.positionsArr[index][2] = Number(Placemark.value.height) - Number(groundHeight) : Placemark.value.height = heightAGL.value = wayLineFrom.value.positionsArr[index][2] - groundHeight }
      else if (heightMode.value === 'relativeToStartPoint') { control==='MoveHXD' ? wayLineFrom.value.positionsArr[index][2] = Number(Placemark.value.height) + Number(takeOffRefPointAGLHeight.value) + Number(takeOffRefPointH.value) : Placemark.value.height = heightALT.value = wayLineFrom.value.positionsArr[index][2] - Number(takeOffRefPointAGLHeight.value) - Number(takeOffRefPointH.value) }
      else if (heightMode.value === 'EGM96') { control==='MoveHXD' ? wayLineFrom.value.positionsArr[index][2] = Number(Placemark.value.height) : Placemark.value.height = globalHeight.value = wayLineFrom.value.positionsArr[index][2] }
    }
    wayLineFrom.value.positionsArr[index][0] = pointLon.value
    wayLineFrom.value.positionsArr[index][1] = pointLat.value
    glayer.graphics[3 * index].setCallbackPosition(wayLineFrom.value.positionsArr[index])
    glayer.graphics[3 * index + 1].setCallbackPosition([groundPosition[0], groundPosition[1], groundHeight] as any)
    glayer.graphics[(3 * index) + 2].setCallbackPositions([[groundPosition[0], groundPosition[1], groundHeight], wayLineFrom.value.positionsArr[index]] as any)
    if (['toPointAndStopWithContinuityCurvature','toPointAndPassWithContinuityCurvature'].includes(wayLineFrom.value.globalWaypointTurnMode)) {
      glayer.removeGraphic(glayer.graphics[glayer.graphics.length - 1])
      resetRoad(wayLineFrom.value.positionsArr)
    } else {
      glayer.graphics[glayer.graphics.length - 1].setCallbackPositions(wayLineFrom.value.positionsArr)
    }
    if (((window as any).QFDLayer?.graphics?.length ?? 0) >= 1) resetQFD('ISResetAllHXD')
  } else if (control === 'AllHXD' || control === 'ISResetQFD') {
    const updates = wayLineFrom.value.Placemark.map((item: any, index: number) => {
      return mars3d.PointUtil.getSurfaceHeight((window as any).map.scene, [wayLineFrom.value.positionsArr[index][0] as any, wayLineFrom.value.positionsArr[index][1] as any] as any).then((result: any) => {
        const groundPosition = wayLineFrom.value.positionsArr[index]
        if (item.useGlobalHeight == '1') {
          if (heightMode.value === 'aboveGroundLevel') { item.height = heightAGL.value; wayLineFrom.value.positionsArr[index][2] = result.height + heightAGL.value }
          else if (heightMode.value === 'relativeToStartPoint') { item.height = heightALT.value; wayLineFrom.value.positionsArr[index][2] = Number(takeOffRefPointAGLHeight.value) + Number(heightALT.value) + Number(takeOffRefPointH.value) }
          else if (heightMode.value === 'EGM96') { item.height = globalHeight.value; wayLineFrom.value.positionsArr[index][2] = globalHeight.value }
          ;(window as any).graphicLayer.graphics[3 * index].setCallbackPosition(wayLineFrom.value.positionsArr[index])
          ;(window as any).graphicLayer.graphics[(3 * index) + 2].setCallbackPositions([[groundPosition[0], groundPosition[1], result.height], wayLineFrom.value.positionsArr[index]] as any)
        } else {
          if (heightMode.value === 'aboveGroundLevel') { item.height = wayLineFrom.value.positionsArr[index][2] - result.height }
          else if (heightMode.value === 'relativeToStartPoint') { item.height = wayLineFrom.value.positionsArr[index][2] - Number(takeOffRefPointAGLHeight.value) - Number(takeOffRefPointH.value) }
          else if (heightMode.value === 'EGM96') { item.height = wayLineFrom.value.positionsArr[index][2] }
        }
      })
    })
    await Promise.all(updates)
    if (['toPointAndStopWithContinuityCurvature','toPointAndPassWithContinuityCurvature'].includes(wayLineFrom.value.globalWaypointTurnMode)) {
      ;(window as any).graphicLayer.removeGraphic((window as any).graphicLayer.graphics[(window as any).graphicLayer.graphics.length - 1])
      resetRoad(wayLineFrom.value.positionsArr)
    } else {
      ;(window as any).graphicLayer.graphics[(window as any).graphicLayer.graphics.length - 1].setCallbackPositions(wayLineFrom.value.positionsArr)
    }
    if (((window as any).QFDLayer?.graphics?.length ?? 0) >= 1) resetQFD('ISResetAllHXD')
  }
  const graphic = (window as any).graphicLayer.graphics[(window as any).graphicLayer.graphics.length - 1]
  distance.value = graphic?.distance ?? 0
}

let addPosition: ReturnType<typeof setInterval> | null = null
function startMoveQFD(type: string, control: string) {
  addPosition = setInterval(() => { if (type==='up') positionUp(control); else if (type==='right') positionRight(control); else if (type==='left') positionLeft(control); else if (type==='down') positionDown(control) }, 500)
}
function endMoveQFD() { if (addPosition) clearInterval(addPosition) }

function changeTakeOffRefPointH(arr: string, num: number) {
  if (arr === 'takeOffRefPointH') {
    takeOffRefPointH.value = Number(takeOffRefPointH.value) + num
    if (takeOffRefPointH.value < -500) takeOffRefPointH.value = -500
    else if (takeOffRefPointH.value > 500) takeOffRefPointH.value = 500
    wayLineFrom.value.takeOffRefPointAGLHeight = takeOffRefPointH.value
    resetQFD('ISResetQFD')
  } else if (arr === 'takeOffSecurityHeight') {
    takeOffSecurityHeight.value = Number(takeOffSecurityHeight.value) + num
    if (takeOffSecurityHeight.value <= 2) takeOffSecurityHeight.value = 2
    else if (takeOffSecurityHeight.value >= 1500) takeOffSecurityHeight.value = 1500
    wayLineFrom.value.takeOffSecurityHeight = takeOffSecurityHeight.value
    if (((window as any).QFDLayer?.graphics?.length ?? 0) >= 1) resetQFD('QFD')
    resetQFD('AllHXD')
  } else if (arr === 'heightAGL') {
    heightAGL.value = Number(heightAGL.value) + num
    if (heightAGL.value < 0) heightAGL.value = 0
    else if (heightAGL.value > 1500) heightAGL.value = 1500
    resetQFD('AllHXD')
  } else if (arr === 'heightALT') {
    heightALT.value = Number(heightALT.value) + num
    if (heightALT.value < -1500) heightALT.value = -1500
    else if (heightALT.value > 1500) heightALT.value = 1500
    resetQFD('AllHXD')
  } else if (arr === 'globalHeight') {
    Placemark.value.useGlobalHeight ? height.value = globalHeight.value = Number(globalHeight.value) + num : globalHeight.value = Number(globalHeight.value) + num
    if (globalHeight.value < -500) globalHeight.value = -500
    else if (globalHeight.value > 10000) globalHeight.value = 10000
    resetQFD('AllHXD')
  } else if (arr === 'heightWGS84') {
    heightWGS84.value = Number(heightWGS84.value) + num
    if (heightWGS84.value < -500) heightWGS84.value = -500
    else if (heightWGS84.value > 10000) heightWGS84.value = 10000
  } else if (arr === 'PlacemarkHeight' && Placemark.value.useGlobalHeight !== '1') {
    Placemark.value.height = Number(Placemark.value.height) + num
    if (Placemark.value.height < 0) Placemark.value.height = 0
    else if (Placemark.value.height > 1500) Placemark.value.height = 1500
    resetQFD('MoveHXD')
  }
}

const visible = ref<boolean>(false)
function checkQFD() { visible.value = true }
function unchanged() {
  if (((window as any).QFDLayer?.graphics?.length ?? 0) >= 1 && heightMode.value === 'relativeToStartPoint') {
    wayLineFrom.value.Placemark.forEach((item: any) => { item.useGlobalHeight = 0 })
  } else if (((window as any).QFDLayer?.graphics?.length ?? 0) < 1 && heightMode.value === 'relativeToStartPoint') setQFD()
  resetQFD('AllHXD')
  wayLineFrom.value.globalHeight = globalHeight.value = heightALT.value = heightAGL.value
  wayLineFrom.value.waylineCoordinateSysParam.heightMode = heightModecopy.value = heightMode.value
  visible.value = false
}
function reset() {
  if (((window as any).QFDLayer?.graphics?.length ?? 0) < 1 && heightMode.value === 'relativeToStartPoint') setQFD()
  resetQFD('AllHXD')
  wayLineFrom.value.waylineCoordinateSysParam.heightMode = heightModecopy.value = heightMode.value
  visible.value = false
}

function changeAutoFlightSpeed() { wayLineFrom.value.Placemark.forEach((item: any) => { if (item.useGlobalSpeed == '1') item.waypointSpeed = wayLineFrom.value.autoFlightSpeed }) }
function changeWaypointHeadingMode(e: string) { wayLineFrom.value.waypointHeadingMode = e }
function changeGimbalPitchMode(e: string) { wayLineFrom.value.gimbalPitchMode = e }
function changeGlobalWaypointTurnMode(e: string) {
  wayLineFrom.value.globalWaypointTurnMode = e
  const glayer: any = (window as any).graphicLayer
  glayer.removeGraphic(glayer.graphics[glayer.graphics.length - 1])
  resetRoad(wayLineFrom.value.positionsArr)
  if (['coordinateTurn','toPointAndStopWithDiscontinuityCurvature'].includes(e)) wayLineFrom.value.Placemark.forEach((i:any)=>{ i.useStraightLine='1' })
  else wayLineFrom.value.Placemark.forEach((i:any)=>{ i.useStraightLine='0' })
}
function changeFinishAction(e: string) { wayLineFrom.value.finishAction = e }

function onToggleFlyToWaylineMode(checked: boolean) {
  flyToWaylineMode.value = checked
  wayLineFrom.value.flyToWaylineMode = checked ? 'pointToPoint' : 'safely'
}

function changeUseGlobalHeight(e: any) { if (e.target.checked) { Placemark.value.useGlobalHeight = '1'; resetQFD('MoveHXD') } else Placemark.value.useGlobalHeight = '0' }
function changeUseGlobalTurnParam(e: any) { Placemark.value.useGlobalTurnParam = e.target.checked ? '1' : '0' }
function changeSelectUseGlobalTurnParam(e: string) { Placemark.value.waypointTurnParam.waypointTurnMode = e; Placemark.value.useStraightLine = ['coordinateTurn','toPointAndStopWithDiscontinuityCurvature'].includes(e)?'1':'0' }
function changeUseGlobalHeadingParam(e: any) { if (e.target.checked) { Placemark.value.useGlobalHeadingParam = '1'; Placemark.value.waypointHeadingParam.waypointHeadingMode = wayLineFrom.value.globalWaypointHeadingParam.waypointHeadingMode } else Placemark.value.useGlobalHeadingParam = '0' }
function changeSelectUseGlobalHeadingParam(e: string) { Placemark.value.waypointHeadingParam.waypointHeadingMode = e }
function changeuseGlobalSpeed(e: any) { if (e.target.checked) { Placemark.value.useGlobalSpeed = '1'; Placemark.value.waypointSpeed = wayLineFrom.value.autoFlightSpeed } else Placemark.value.useGlobalSpeed = '0' }

const selectActionGroup = ref<number>(-1)
const selectActionAction = ref<number>(-1)
function selectAction(actionGroupId: number, actionId: number) { if (selectActionGroup.value === actionGroupId && selectActionAction.value === actionId) { selectActionGroup.value = -1; selectActionAction.value = -1 } else { selectActionGroup.value = actionGroupId; selectActionAction.value = actionId } }
function orientedFileSuffixEditstartEdit(e: string, actionId: string) { orientedFileSuffixEdit.value = !orientedFileSuffixEdit.value; orientedFileSuffix.value = e; orientedActionId.value = actionId }
function delAction(actionGroupId: any, actionId: any) { Placemark.value.actionGroup.forEach((element: any) => { if (element.actionGroupId == actionGroupId) { element.action.splice(actionId,1); element.action.forEach((item: any, index: number) => { item.actionId = index }) } }) }
function onStart(_e: any) {}
function onEnd(e: any) { try { Placemark.value.actionGroup[0].action[e.newIndex].actionId = e.newIndex; Placemark.value.actionGroup[0].action[e.oldIndex].actionId = e.oldIndex } catch {}
}

// slider update handlers (avoid implicit any in templates)
function onUpdateAutoFlightSpeed(v: number | string) { wayLineFrom.value.autoFlightSpeed = Number(v) }
function onUpdateWaypointSpeed(v: number | string) { Placemark.value.waypointSpeed = Number(v) }
function onUpdateGimbalPitch(v: number | string) { Placemark.value.gimbalPitchAngle = Number(v) }
function onUpdateFlightControlSpeed(v: number | string) { (flightControl as any).value ? (flightControl as any).value.speed = Number(v) : (flightControl as any).speed = Number(v) }
function openPointPanel() { showpointInfo.value = true }

function highlightWaypoint(index: number) {
  try {
    const glayer: any = (window as any).graphicLayer
    if (!glayer || !Array.isArray(glayer.graphics)) return
    const total = wayLineFrom.value?.Placemark?.length ?? 0
    for (let i = 0; i < total; i++) {
      const ground = glayer.graphics[3 * i + 1]
      try { ground?.setStyle?.({ color: '#000', pixelSize: 10, clampToGround: true }) } catch {}
    }
    const selGround = glayer.graphics[3 * index + 1]
    try { selGround?.setStyle?.({ color: '#ff0000', pixelSize: 15, clampToGround: true }) } catch {}
  } catch {}
}

function syncPointPanelByIndex(index: number) {
  const total = wayLineFrom.value?.Placemark?.length ?? 0
  if (total <= 0) { showpointInfo.value = false; return }
  const nextIdx = Math.max(0, Math.min(index, total - 1))
  PlacemarkNum.value = nextIdx
  Placemark.value = wayLineFrom.value.Placemark[nextIdx]
  try {
    const coords = wayLineFrom.value.positionsArr[nextIdx]
    pointLon.value = Number(coords?.[0])
    pointLat.value = Number(coords?.[1])
    pointH.value = Number(coords?.[2] ?? 0)
  } catch {}
  wayLinePointName.value = `航点${nextIdx + 1}`
  showpointInfo.value = true
  highlightWaypoint(nextIdx)
}

function prevWaypoint() { syncPointPanelByIndex((PlacemarkNum.value ?? 0) - 1) }
function nextWaypoint() { syncPointPanelByIndex((PlacemarkNum.value ?? 0) + 1) }

async function createWayPoint(e: number[], index: number) {
  const pm = {
    Point: { coordinates: `${e[0]},${e[1]}` }, index, useGlobalHeight: 1, ellipsoidHeight: wayLineFrom.value.globalHeight, height: wayLineFrom.value.globalHeight,
    useGlobalSpeed: 1, waypointSpeed: wayLineFrom.value.autoFlightSpeed, useGlobalHeadingParam: 1,
    waypointHeadingParam: { waypointHeadingMode: waypointHeadingMode.value, waypointHeadingAngle: 0, waypointHeadingPathMode: 'followBadArc', waypointPoiPoint: '0,0,0', waypointHeadingPoiIndex: 0 },
    useGlobalTurnParam: 1, waypointTurnParam: { waypointTurnMode: waypointHeadingMode.value, waypointTurnDampingDist: 0.2 }, useStraightLine: 0, gimbalPitchAngle: 0, actionGroup: []
  }
  pm.useStraightLine = ['coordinateTurn','toPointAndStopWithDiscontinuityCurvature'].includes(wayLineFrom.value.globalWaypointTurnMode) ? 1 : 0
  wayLineFrom.value.Placemark.push(pm)
  wayLineFrom.value.positionsArr.push(e)
  if (wayLineFrom.value.waylineCoordinateSysParam.heightMode === 'aboveGroundLevel') {
    wayLineFrom.value.positionsArr[index][2] = (e[2] ?? 0) + pm.height * 1
  } else if (wayLineFrom.value.waylineCoordinateSysParam.heightMode === 'relativeToStartPoint') {
    const QFDposition = [wayLineFrom.value.takeOffRefPoint.split(',')[1], wayLineFrom.value.takeOffRefPoint.split(',')[0], wayLineFrom.value.takeOffRefPoint.split(',')[2]]
    wayLineFrom.value.positionsArr[index][2] = Number(QFDposition[2]) + Number(pm.height) + Number(wayLineFrom.value.takeOffRefPointAGLHeight)
  } else if (wayLineFrom.value.waylineCoordinateSysParam.heightMode === 'EGM96') {
    wayLineFrom.value.positionsArr[index][2] = pm.height * 1
  }
  await selectRoute()
}

function addAction(flag: string) {
  let action: any = {}
  let actionGroup: any = {}
  if (Placemark.value.actionGroup.length === 0 && flag !== 'multipleTiming' && flag !== 'multipleDistance') {
    actionGroup = { actionGroupId: '', actionGroupStartIndex: PlacemarkNum.value, actionGroupEndIndex: PlacemarkNum.value, actionGroupMode: 'sequence', actionTrigger: { actionTriggerType: 'reachPoint' }, action: [] }
    Placemark.value.actionGroup.push(actionGroup)
  }
  if (flag === 'xt') {
    action = { actionId: Placemark.value.actionGroup[0].action.length, actionActuatorFunc: 'hover', actionActuatorFuncParam: { hoverTime: 10 } }
    Placemark.value.actionGroup[0].action.push(action)
  } else if (flag === 'fxqphj') {
    action = { actionId: Placemark.value.actionGroup[0].action.length, actionActuatorFunc: 'rotateYaw', actionActuatorFuncParam: { aircraftHeading: 0, aircraftPathMode: 'counterClockwise' } }
    Placemark.value.actionGroup[0].action.push(action)
  } else if (flag === 'ytphj' || flag === 'ytfyj') {
    action = { actionId: Placemark.value.actionGroup[0].action.length, actionActuatorFunc: 'gimbalRotate', actionActuatorFuncParam: { gimbalHeadingYawBase: 'north', gimbalRotateMode: 'absoluteAngle', gimbalPitchRotateEnable: 0, gimbalPitchRotateAngle: 0, gimbalRollRotateEnable: 0, gimbalRollRotateAngle: 0, gimbalYawRotateEnable: 1, gimbalYawRotateAngle: 0, gimbalRotateTimeEnable: 0, gimbalRotateTime: 0, payloadPositionIndex: 0 } }
    flag === 'ytphj' ? [action.actionActuatorFuncParam.gimbalYawRotateEnable = 1, action.actionActuatorFuncParam.gimbalPitchRotateEnable = 0] : [action.actionActuatorFuncParam.gimbalYawRotateEnable = 0, action.actionActuatorFuncParam.gimbalPitchRotateEnable = 1]
    Placemark.value.actionGroup[0].action.push(action)
  } else if (flag === 'dxpz') {
    action = { actionId: Placemark.value.actionGroup[0].action.length, actionActuatorFunc: 'orientedShoot', actionActuatorFuncParam: { gimbalPitchRotateAngle:0, gimbalRollRotateAngle:0, gimbalYawRotateAngle:0, psjd:0, focusX:0, focusY:0, focusRegionWidth:0, focusRegionHeight:0, focalLength:120, xjbj:5, aircraftHeading:0, accurateFrameValid:0, payloadPositionIndex:0, useGlobalPayloadLensIndex:1, gshx:true, payloadLensIndex:'wide,zoom', gshxW:wide.value, gshxZ:zoom.value, targetAngle:0, actionUUID:'', imageWidth:0, imageHeight:0, AFPos:0, gimbalPort:0, orientedCameraType:53, orientedFilePath:'', orientedFileSize:0, orientedFileSuffix:'', orientedPhotoMode:'lowLightSmartShooting' } }
    const gid = ((window as any)?.graphicLayer?.graphics && (window as any).graphicLayer.graphics[PlacemarkNum.value * 3] && (window as any).graphicLayer.graphics[PlacemarkNum.value * 3]._id) ? (window as any).graphicLayer.graphics[PlacemarkNum.value * 3]._id : ''
    action.actionActuatorFuncParam.actionUUID = action.actionActuatorFuncParam.orientedFilePath = gid
    action.payloadLensIndex = wayLineFrom.value.payloadParam.imageFormat
    Placemark.value.actionGroup[0].action.push(action)
  } else if (flag === 'pz') {
    action = { actionId: Placemark.value.actionGroup[0].action.length, actionActuatorFunc: 'takePhoto', actionActuatorFuncParam: { fileSuffix: '', payloadPositionIndex: 0, useGlobalPayloadLensIndex: 1, gshx:true, payloadLensIndex: '', gshxW:wide.value, gshxZ:zoom.value, orientedFileSuffix:'' } }
    action.payloadLensIndex = wayLineFrom.value.payloadParam.imageFormat
    Placemark.value.actionGroup[0].action.push(action)
  } else if (flag === 'kslx') {
    action = { actionId: Placemark.value.actionGroup[0].action.length, actionActuatorFunc: 'startRecord', actionActuatorFuncParam: { payloadPositionIndex: 0, useGlobalPayloadLensIndex: 1, gshx:true, gshxW:wide.value, gshxZ:zoom.value, orientedFileSuffix:'' } }
    Placemark.value.actionGroup[0].action.push(action)
  } else if (flag === 'tzlx') {
    action = { actionId: Placemark.value.actionGroup[0].action.length, actionActuatorFunc: 'stopRecord', actionActuatorFuncParam: { payloadPositionIndex: 0 } }
    Placemark.value.actionGroup[0].action.push(action)
  } else if (flag === 'xjbj') {
    action = { actionId: Placemark.value.actionGroup[0].action.length, actionActuatorFunc: 'zoom', actionActuatorFuncParam: { focalLength: 120, xjbj:5, isUseFocalFactor: 0, payloadPositionIndex: 0 } }
    Placemark.value.actionGroup[0].action.push(action)
  } else if (flag === 'cjwjj') {
    action = { actionId: Placemark.value.actionGroup[0].action.length, actionActuatorFunc: 'customDirName', actionActuatorFuncParam: { payloadPositionIndex: 0, orientedFileSuffix:'' } }
    Placemark.value.actionGroup[0].action.push(action)
  } else if (flag === 'multipleTiming' || flag === 'multipleDistance') {
    let addFlag = true
    for (let i=0;i<Placemark.value.actionGroup.length;i++) {
      if (['multipleTiming','multipleDistance'].includes(Placemark.value.actionGroup[i].actionTrigger.actionTriggerType)) { addFlag = false; message.error('该航点已存在间隔拍照') }
    }
    if (addFlag) {
      const actionGroupTime = { actionGroupId: '', actionGroupStartIndex: PlacemarkNum.value, actionGroupEndIndex: wayLineFrom.value.Placemark.length-1, actionGroupMode: 'sequence', actionTrigger: { actionTriggerType: flag, actionTriggerParam: '3' }, action: [{ actionId:0, actionActuatorFunc:'takePhoto', actionActuatorFuncParam:{ payloadPositionIndex:0, useGlobalPayloadLensIndex:1, payloadLensIndex:'', gshx:true, gshxW:wide.value, gshxZ:zoom.value } }] }
      ;(actionGroupTime as any).action[0].actionActuatorFuncParam.payloadLensIndex = wayLineFrom.value.payloadParam.imageFormat
      for (let i=PlacemarkNum.value;i<=wayLineFrom.value.Placemark.length-1;i++) {
        wayLineFrom.value.Placemark[i].actionGroup.forEach((ag: any) => { ag.action.forEach((a: any) => { if (a.actionActuatorFunc === 'actionGroupEndIndex') (actionGroupTime as any).actionGroupEndIndex = i }) })
      }
      Placemark.value.actionGroup.push(actionGroupTime)
      checkStop()
    }
  } else if (flag === 'end') {
    const arr = { actionActuatorFunc: 'actionGroupEndIndex', actionGroupStartIndex: PlacemarkNum.value, actionGroupEndIndex: PlacemarkNum.value }
    if (!Placemark.value.actionGroup[0]) Placemark.value.actionGroup.push({ actionGroupId:'0', actionGroupStartIndex: PlacemarkNum.value, actionGroupEndIndex: PlacemarkNum.value, actionGroupMode: 'sequence', actionTrigger: { actionTriggerType: 'reachPoint' }, action: [] })
    Placemark.value.actionGroup[0].action.push(arr)
  }
}

function checkStop() {
  for (let i=0;i<wayLineFrom.value.Placemark.length;i++) {
    wayLineFrom.value.Placemark[i].actionGroup.forEach((actionGroup: any) => {
      if (['multipleTiming','multipleDistance'].includes(actionGroup.actionTrigger.actionTriggerType)) {
        let flag = 0
        const startType = actionGroup.actionTrigger.actionTriggerType === 'multipleTiming' ? '开始等时间隔拍照' : '开始等距间隔拍照'
        for (let m=i+1;m<wayLineFrom.value.Placemark.length;m++) {
          wayLineFrom.value.Placemark[m].actionGroup.forEach((actionGroup2: any) => {
            actionGroup2.action.forEach((action: any) => {
              if (action.actionActuatorFunc === 'takePhoto') {
                let checkTakePhotoFlag = false
                const endType = actionGroup2.actionTrigger.actionTriggerType === 'multipleTiming' ? '开始等时间隔拍照' : '开始等距间隔拍照'
                for (let x=i+1;x<=m;x++) {
                  wayLineFrom.value.Placemark[x].actionGroup.forEach((checkTakePhoto: any) => {
                    for (let n=0;n<checkTakePhoto.action.length;n++) { if (checkTakePhoto.action[n].actionActuatorFunc === 'actionGroupEndIndex') { checkTakePhotoFlag=true; break } }
                  })
                  if (checkTakePhotoFlag) break
                }
                if (!checkTakePhotoFlag && flag === 0) {
                  if (startType !== endType) message.warning(`问题: ${i+1}#, ${m+1}#航点的"${startType}"/"${endType}"航点动作间缺少"结束间隔拍照"动作。`)
                  else message.warning(`问题: ${i+1}#, ${m+1}#航点的"${startType}"航点动作间缺少"结束间隔拍照"动作。`)
                  flag++
                }
              }
            })
          })
        }
      }
    })
  }
}

async function sureDetGraphic () {
  try {
  const idx = PlacemarkNum.value
  const glayer: any = (window as any).graphicLayer
    try { glayer?.graphics?.[idx * 3 + 1]?.stopEditing?.() } catch {}

    // 删除数据源中的航点与坐标
  wayLineFrom.value.Placemark.splice(idx, 1)
  wayLineFrom.value.positionsArr.splice(idx, 1)

    // 重新编号 index 字段
  wayLineFrom.value.Placemark.forEach((element: any, index: number) => { element.index = index })

    // 调整当前选中索引并同步当前航点引用
    const total = wayLineFrom.value.Placemark.length
    if (total > 0) {
      PlacemarkNum.value = Math.min(idx, total - 1)
      Placemark.value = wayLineFrom.value.Placemark[PlacemarkNum.value]
    } else {
      PlacemarkNum.value = 0
      showpointInfo.value = false
    }

    // 重新绘制航线实例
    await selectRoute()
    // 基于当前高度模式与起飞点参数，重算全部航点高度并刷新折线
    try { await resetQFD('AllHXD') } catch {}

    // 标记已修改
    isChanged.value = true
  } finally {
  detGraphicFlag.value = false
  }
}

// 暴露方法给父级（App.vue）调用
async function exportCommonKml() {
  try {
    const positions = Array.isArray(wayLineFrom.value?.positionsArr) ? wayLineFrom.value.positionsArr : []
    if (!positions.length) {
      message.error('暂无航点可导出')
      return
    }

    // 参考 hx.kml 生成通用KML（单一LineString样式）
    const name = routeName.value || '未命名线_1'
    const coordLines = positions
      .map((p: number[]) => `          ${p[0]},${p[1]},0`)
      .join('\n')
    const kml = `<?xml version="1.0" encoding="UTF-8"?>\n` +
`<kml>\n` +
`  <Document>\n` +
`    <Placemark>\n` +
`      <name>${name}</name>\n` +
`      <visibility>1</visibility>\n` +
`      <Style>\n` +
`        <LineStyle>\n` +
`          <color>ff7fff7f</color>\n` +
`          <width>0.800000011920929</width>\n` +
`        </LineStyle>\n` +
`      </Style>\n` +
`      <ExtendedData>\n` +
`        <Data name="LinePattern">\n` +
`          <value>65535</value>\n` +
`        </Data>\n` +
`      </ExtendedData>\n` +
`      <LineString>\n` +
`        <altitudeMode>clampToGround</altitudeMode>\n` +
`        <coordinates>\n` +
`${coordLines}\n` +
`        </coordinates>\n` +
`      </LineString>\n` +
`    </Placemark>\n` +
`  </Document>\n` +
`</kml>\n`

    const blob = new Blob([kml], { type: 'application/vnd.google-earth.kml+xml' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `${routeName.value || 'wayline'}.kml`
    a.click()
    URL.revokeObjectURL(url)
    message.success('通用KML导出成功')
  } catch (err) {
    console.error('导出通用KML失败', err)
    message.error('导出失败')
  }
}

function openFlightParams() { isFlightPanel.value = true }
function toggleFlightParams() { isFlightPanel.value = !isFlightPanel.value }

function generateFlightControllerKml(): string {
  const pts = Array.isArray(wayLineFrom.value?.positionsArr) ? wayLineFrom.value.positionsArr : []
  const name = routeName.value || 'Waypoints'
  const altitude = Number((flightControl as any).value ? (flightControl as any).value.altitude : (flightControl as any).altitude) || 0
  const speed = Number((flightControl as any).value ? (flightControl as any).value.speed : (flightControl as any).speed) || Number(wayLineFrom.value?.autoFlightSpeed || 0)
  const turnMode = (flightControl as any).value ? (flightControl as any).value.turnMode : (flightControl as any).turnMode
  const hoverTime = Number((flightControl as any).value ? (flightControl as any).value.hoverTime : (flightControl as any).hoverTime) || 0
  const missionMode = (flightControl as any).value ? (flightControl as any).value.missionMode : (flightControl as any).missionMode
  const photoMode = (flightControl as any).value ? (flightControl as any).value.photoMode : (flightControl as any).photoMode
  const timeInterval = Number((flightControl as any).value ? (flightControl as any).value.timeInterval : (flightControl as any).timeInterval) || 0
  const distanceInterval = Number((flightControl as any).value ? (flightControl as any).value.distanceInterval : (flightControl as any).distanceInterval) || 0

  const toTurnType = (m: any) => (m === 'waypoint' ? 1 : 0)
  const toTaskType = (m: any) => (m === 'photo' ? 1 : 0)
  const toTakePhotoMode = (m: any) => (m === 'time' ? 1 : 2)
  const toTaskValue = () => (photoMode === 'time' ? timeInterval : distanceInterval)

  let kmlContent = ''
  pts.forEach((p: any, idx: number) => {
    if (!Array.isArray(p) || p.length < 2) return
    const lng = p[0]
    const lat = p[1]
    const coordAlt = altitude
    const centerLon = lng
    const centerLat = lat
    kmlContent += `
  <Placemark>
   <name>Waypoint${idx + 1}</name>
   <Point>
    <coordinates>${lng},${lat},${coordAlt}</coordinates>
   </Point>
   <description>
    <CenterID>${idx}</CenterID>
    <CenterLongitude>${centerLon}</CenterLongitude>
    <CenterLatitude>${centerLat}</CenterLatitude>
    <Speed>${speed}</Speed>
    <TurnType>${toTurnType(turnMode)}</TurnType>
    <TurnParam1>2</TurnParam1>
    <TurnParam2>2</TurnParam2>
    <TaskType>${toTaskType(missionMode)}</TaskType>
    <TaskValue>${toTaskValue()}</TaskValue>
    <HoverTime>${turnMode === 'waypoint' ? hoverTime : 0}</HoverTime>
    <TakePhotoAction>${missionMode === 'photo' ? 1 : 0}</TakePhotoAction>
    <TakePhotoMode>${missionMode === 'photo' ? toTakePhotoMode(photoMode) : 0}</TakePhotoMode>
    <TakePhotoInterval>${missionMode === 'photo' ? (photoMode === 'time' ? timeInterval : distanceInterval) : 0}</TakePhotoInterval>
    <YuntaiAction>0</YuntaiAction>
    <YuntaiPitch>0</YuntaiPitch>
    <YuntaiHeading>0</YuntaiHeading>
    <HeadingMode>2</HeadingMode>
    <HeadingValue>0</HeadingValue>
    <ThrowHeight>0</ThrowHeight>
    <ThrowChannel>0</ThrowChannel>
    <CircleRadius>0</CircleRadius>
    <CircleSpeed>0</CircleSpeed>
    <CircleTurns>0</CircleTurns>
    <WaypointType>0</WaypointType>
    <Dis>0</Dis>
    <LogisticsType>0</LogisticsType>
    <WaypointTypeMode>121</WaypointTypeMode>
    <WptDimianHaiba>nan</WptDimianHaiba>
   </description>
  </Placemark>`
  })

  const header = `<kml xmlns:kml="http://www.opengis.net/kml/2.2">
 <Document>
  <name>${name}</name>`
  const footer = `
 </Document>
</kml>
`
  return header + kmlContent + footer
}

async function exportFlightKml() {
  try {
    const pts = Array.isArray(wayLineFrom.value?.positionsArr) ? wayLineFrom.value.positionsArr : []
    if (!pts.length) { message.error('暂无航点可导出'); return }
    const content = generateFlightControllerKml()
    const blob = new Blob([content], { type: 'application/vnd.google-earth.kml+xml' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `${routeName.value || 'flight-control'}.kml`
    a.click()
    URL.revokeObjectURL(url)
    message.success('飞控KML导出成功')
  } catch (err) {
    console.error('导出飞控KML失败', err)
    message.error('导出失败')
  }
}

defineExpose({ save, goback, deleteCurrent, isChanged, exportCommonKml, exportFlightKml, openFlightParams, toggleFlightParams, isFlightPanel })
</script>

<template>
  <!-- eslint-disable vue/no-v-model-argument -->
  <div class="edit-wayLine">

    <div class="editmain">
      <div class="left-box" v-show="showLeftBox">
        <div class="component-wayline-preset-info">
          <div class="name-and-device">
            <span>wpmz</span>
            <div class="mt5">
              <span>{{ droneName }}</span>
              <span class="ml10">相机</span>
              <span class="ml5">{{ payloadName }}</span>
            </div>
          </div>
          <!-- <div class="transform-wrapper" @click="isFlightPanel = !isFlightPanel">
            <span>切换</span>
          </div> -->
        </div>

        <div v-if="!isFlightPanel" class="basic-form-group-overview-items basic-form-group-overview-display">
          <a-collapse expandIconPosition="right">
            <a-collapse-panel key="1" header="负载设置">
              <div class="payload-item-info">云台 I: {{ payloadName }}</div>
              <div class="settings-list">
                <div class="dynamic-form-item-label-left"><span>照片存储类型设置</span></div>
                <div class="check_box">
                  <a-checkbox :disabled="!zoom" @change="changeImageFormat" v-model:checked="wide">广角(W)</a-checkbox>
                  <a-checkbox :disabled="!wide" @change="changeImageFormat" v-model:checked="zoom">变焦(Z)</a-checkbox>
                </div>
              </div>
            </a-collapse-panel>
          </a-collapse>

          <div class="item_box">
            <div class="option"><div class="label">航线长度</div><div class="value">{{ Math.floor(distance) }}<span class="unit"> m</span></div></div>
            <div class="option"><div class="label">航点</div><div class="value">{{ wayLineFrom.Placemark.length }}</div></div>
          </div>

          <div class="item_box">
            <a-button size="small" type="primary" @click="openPointPanel">打开航点面板</a-button>
          </div>

          <div class="item_box">
            <div class="basicModelLR">
              <div class="left"><span>智能低光</span></div>
              <a-switch v-model:checked="orientedPhotoMode" />
            </div>
          </div>

          <div class="item_box qfd">
            <div class="basicModelLR">
              <div class="left"><span>起飞点设置 (AGL)</span></div>
              <div class="right" @click="setQFD()" v-show="!qfdIsShow">设置起飞点</div>
              <div class="right" @click="delQFD()" v-show="qfdIsShow">删除起飞点</div>
            </div>
            <div class="ModelLRControl" v-show="qfdIsShow">
              <div class="takeoffPointPosition">
                <div class="position">
                  <div class="lon"><div class="label">经度</div><a-input v-model:value="takeOffRefPointLon" @change="resetQFD('QFD')" /></div>
                  <div class="lat"><div class="label">纬度</div><a-input v-model:value="takeOffRefPointLat" @change="resetQFD('QFD')" /></div>
                </div>
                <div class="controller">
                  <div class="solid-circle"></div>
                  <div class="item up" @click="positionUp('QFD')" @mousedown="startMoveQFD('up','QFD')" @mouseup="endMoveQFD()"><img src="../assets/images/Right Angle.png" alt=""></div>
                  <div class="item right" @click="positionRight('QFD')" @mousedown="startMoveQFD('right','QFD')" @mouseup="endMoveQFD()"><img src="../assets/images/Right Angle.png" alt=""></div>
                  <div class="item left" @click="positionLeft('QFD')" @mousedown="startMoveQFD('left','QFD')" @mouseup="endMoveQFD()"><img src="../assets/images/Right Angle.png" alt=""></div>
                  <div class="item down" @click="positionDown('QFD')" @mousedown="startMoveQFD('down','QFD')" @mouseup="endMoveQFD()"><img src="../assets/images/Right Angle.png" alt=""></div>
                </div>
              </div>
              <div class="height">
                <div class="label">对地高度</div>
                <div class="height_control">
                  <span :class="takeOffRefPointH<=-500?'disabled':''" @click="changeTakeOffRefPointH('takeOffRefPointH',-100)">-100</span>
                  <span :class="takeOffRefPointH<=-500?'disabled':''" @click="changeTakeOffRefPointH('takeOffRefPointH',-10)">-10</span>
                  <span :class="takeOffRefPointH<=-500?'disabled':''" @click="changeTakeOffRefPointH('takeOffRefPointH',-1)">-1</span>
                  <a-input style="width:57px;" :disabled="takeOffRefPointH<=-500||takeOffRefPointH>=500" v-model:value="takeOffRefPointH" @change="resetQFD('QFD')" />m
                  <span :class="takeOffRefPointH>=500?'disabled':''" @click="changeTakeOffRefPointH('takeOffRefPointH',+1)">+1</span>
                  <span :class="takeOffRefPointH>=500?'disabled':''" @click="changeTakeOffRefPointH('takeOffRefPointH',+10)">+10</span>
                  <span :class="takeOffRefPointH>=500?'disabled':''" @click="changeTakeOffRefPointH('takeOffRefPointH',+100)">+100</span>
                </div>
              </div>
            </div>
          </div>

          <div class="item_box">
            <div class="basicModelLR mb8"><div class="left"><span>安全起飞高度 (ALT)</span></div></div>
            <div class="height_control mb16">
              <span :class="takeOffSecurityHeight<=2?'disabled':''" @click="changeTakeOffRefPointH('takeOffSecurityHeight',-100)">-100</span>
              <span :class="takeOffSecurityHeight<=2?'disabled':''" @click="changeTakeOffRefPointH('takeOffSecurityHeight',-10)">-10</span>
              <span :class="takeOffSecurityHeight<=2?'disabled':''" @click="changeTakeOffRefPointH('takeOffSecurityHeight',-1)">-1</span>
              <a-input :disabled="takeOffSecurityHeight<=2 || takeOffSecurityHeight>=1500" v-model:value="takeOffSecurityHeight" @change="resetQFD('QFD')" />m
              <span :class="takeOffSecurityHeight>=1500?'disabled':''" @click="changeTakeOffRefPointH('takeOffSecurityHeight',+1)">+1</span>
              <span :class="takeOffSecurityHeight>=1500?'disabled':''" @click="changeTakeOffRefPointH('takeOffSecurityHeight',+10)">+10</span>
              <span :class="takeOffSecurityHeight>=1500?'disabled':''" @click="changeTakeOffRefPointH('takeOffSecurityHeight',+100)">+100</span>
            </div>

            <a-modal v-model:open="visible" title="高度模式转换">
              <template #footer>
                <a-button @click="heightMode = heightModecopy; visible = false">取消</a-button>
                <a-button type="primary" @click="unchanged">保持不变</a-button>
                <a-button type="primary" @click="reset">重新计算</a-button>
              </template>
              <div>航线将转换至"相对起飞点高度"模式...</div>
            </a-modal>

            <div class="basicModelLR mb8"><div class="left"><span>高度模式</span></div></div>
            <a-select v-model:value="heightMode" style="width:328px" popupClassName="gdmsSelect" @select="checkQFD">
              <a-select-option value="EGM96">绝对高度</a-select-option>
              <a-select-option value="relativeToStartPoint">相对起飞点高度</a-select-option>
              <a-select-option value="aboveGroundLevel">相对地面高度</a-select-option>
            </a-select>

            <div v-show="heightMode==='aboveGroundLevel'" style="width:100%;margin-top:16px;">
              <div class="label mb8">相对地面高度</div>
              <div class="height_control mb16">
                <span :class="heightAGL<=0?'disabled':''" @click="changeTakeOffRefPointH('heightAGL',-100)">-100</span>
                <span :class="heightAGL<=0?'disabled':''" @click="changeTakeOffRefPointH('heightAGL',-10)">-10</span>
                <span :class="heightAGL<=0?'disabled':''" @click="changeTakeOffRefPointH('heightAGL',-1)">-1</span>
                <a-input :disabled="heightAGL<=0 || heightAGL>=1500" v-model:value="heightAGL" @change="resetQFD('HXD')" />m
                <span :class="heightAGL>=1500?'disabled':''" @click="changeTakeOffRefPointH('heightAGL',+1)">+1</span>
                <span :class="heightAGL>=1500?'disabled':''" @click="changeTakeOffRefPointH('heightAGL',+10)">+10</span>
                <span :class="heightAGL>=1500?'disabled':''" @click="changeTakeOffRefPointH('heightAGL',+100)">+100</span>
              </div>
            </div>

            <div v-show="heightMode==='relativeToStartPoint'" style="width:100%;margin-top:16px;">
              <div class="label mb8">相对起飞点高度</div>
              <div class="height_control mb16">
                <span :class="heightALT<=-1500?'disabled':''" @click="changeTakeOffRefPointH('heightALT',-100)">-100</span>
                <span :class="heightALT<=-1500?'disabled':''" @click="changeTakeOffRefPointH('heightALT',-10)">-10</span>
                <span :class="heightALT<=-1500?'disabled':''" @click="changeTakeOffRefPointH('heightALT',-1)">-1</span>
                <a-input :disabled="heightALT<=-1500 || heightALT>=1500" v-model:value="heightALT" @change="resetQFD('HXD')" />m
                <span :class="heightALT>=1500?'disabled':''" @click="changeTakeOffRefPointH('heightALT',+1)">+1</span>
                <span :class="heightALT>=1500?'disabled':''" @click="changeTakeOffRefPointH('heightALT',+10)">+10</span>
                <span :class="heightALT>=1500?'disabled':''" @click="changeTakeOffRefPointH('heightALT',+100)">+100</span>
              </div>
            </div>

            <div v-show="heightMode==='EGM96'" style="width:100%;margin-top:5px;">
              <div class="hblabel"><div class="dynamic-form-item-label-left"><span>海拔高度 (EGM96)</span></div></div>
              <div class="content-wrapper">
                <div class="title-bottom"><span>椭球高度 (WGS84)</span></div>
                <div class="absolute-height-slider">
                  <div class="height_control">
                    <span :class="globalHeight<=-500?'disabled':''" @click="changeTakeOffRefPointH('globalHeight',-100)">-100</span>
                    <span :class="globalHeight<=-500?'disabled':''" @click="changeTakeOffRefPointH('globalHeight',-10)">-10</span>
                    <span :class="globalHeight<=-500?'disabled':''" @click="changeTakeOffRefPointH('globalHeight',-1)">-1</span>
                    <a-input :disabled="globalHeight<=-500 || globalHeight>=10000" style="width:57px;" v-model:value="globalHeight" @change="resetQFD('HXD')" />m
                    <span :class="globalHeight>=10000?'disabled':''" @click="changeTakeOffRefPointH('globalHeight',+1)">+1</span>
                    <span :class="globalHeight>=10000?'disabled':''" @click="changeTakeOffRefPointH('globalHeight',+10)">+10</span>
                    <span :class="globalHeight>=10000?'disabled':''" @click="changeTakeOffRefPointH('globalHeight',+100)">+100</span>
                  </div>
                  <div class="height_control">
                    <span :class="heightWGS84<=-500?'disabled':''" @click="changeTakeOffRefPointH('heightWGS84',-100)">-100</span>
                    <span :class="heightWGS84<=-500?'disabled':''" @click="changeTakeOffRefPointH('heightWGS84',-10)">-10</span>
                    <span :class="heightWGS84<=-500?'disabled':''" @click="changeTakeOffRefPointH('heightWGS84',-1)">-1</span>
                    <a-input :disabled="heightWGS84<=-500 || heightWGS84>=10000" style="width:57px;" v-model:value="heightWGS84" @change="resetQFD('HXD')" />m
                    <span :class="heightWGS84>=10000?'disabled':''" @click="changeTakeOffRefPointH('heightWGS84',+1)">+1</span>
                    <span :class="heightWGS84>=10000?'disabled':''" @click="changeTakeOffRefPointH('heightWGS84',+10)">+10</span>
                    <span :class="heightWGS84>=10000?'disabled':''" @click="changeTakeOffRefPointH('heightWGS84',+100)">+100</span>
                  </div>
                </div>
              </div>
            </div>

            <div class="basicModelLR" style="margin-top:16px;">
              <div class="left"><span>飞行速度</span></div>
              <div><a-input :disabled="wayLineFrom.autoFlightSpeed<=1 || wayLineFrom.autoFlightSpeed>=15" style="width:57px;margin:0 5px;" v-model:value="wayLineFrom.autoFlightSpeed" @change="changeAutoFlightSpeed" />m/s</div>
            </div>
            <div class="speadSilder" style="width:100%;"><a-slider :value="Number(wayLineFrom.autoFlightSpeed)" :min="1" :max="15" @update:value="onUpdateAutoFlightSpeed" /></div>

            <div class="basicModelLR mb8"><div class="left"><span>飞行器偏航角模式</span></div></div>
            <a-select v-model:value="waypointHeadingMode" style="width:328px;margin-bottom:16px;" popupClassName="gdmsSelect" @change="changeWaypointHeadingMode">
              <a-select-option value="followWayline">沿航线方向</a-select-option>
              <a-select-option value="manually">手动控制</a-select-option>
              <a-select-option value="fixed">锁定当前偏航角</a-select-option>
            </a-select>

            <div class="basicModelLR mb8"><div class="left"><span>航点类型</span></div></div>
            <a-select v-model:value="globalWaypointTurnMode" style="width:328px;margin-bottom:16px;" popupClassName="gdmsSelect" @change="changeGlobalWaypointTurnMode">
              <a-select-option value="coordinateTurn">协调转弯</a-select-option>
              <a-select-option value="toPointAndStopWithDiscontinuityCurvature">直线飞行到点停</a-select-option>
              <a-select-option value="toPointAndStopWithContinuityCurvature">曲线飞行到点停</a-select-option>
              <a-select-option value="toPointAndPassWithContinuityCurvature">曲线飞行过点不停</a-select-option>
            </a-select>

            <div class="basicModelLR mb8"><div class="left"><span>完成动作</span></div></div>
            <a-select v-model:value="finishAction" style="width:328px;margin-bottom:16px;" popupClassName="gdmsSelect" @change="changeFinishAction">
              <a-select-option value="goHome">自动返航</a-select-option>
              <a-select-option value="noAction">退出航线模式</a-select-option>
              <a-select-option value="autoLand">原地降落</a-select-option>
              <a-select-option value="gotoFirstWaypoint">返回航线起始点悬停</a-select-option>
            </a-select>
          </div>
        </div>

        <div v-else class="basic-form-group-overview-items basic-form-group-overview-display">
          <div class="item_box">
            <div class="basicModelLR mb8"><div class="left"><span>飞控参数</span></div></div>

            <div class="basicModelLR" style="margin-top:8px;">
              <div class="left"><span>飞行高度</span></div>
              <div><a-input style="width:80px;margin:0 5px;" v-model:value="flightControl.altitude" />m</div>
            </div>

            <div class="basicModelLR" style="margin-top:16px;">
              <div class="left"><span>飞行速度</span></div>
              <div><a-input style="width:80px;margin:0 5px;" v-model:value="flightControl.speed" />m/s</div>
            </div>
            <div class="speadSilder" style="width:100%;"><a-slider :value="Number(flightControl.speed)" :min="1" :max="15" @update:value="onUpdateFlightControlSpeed" /></div>

            <div class="basicModelLR mb8"><div class="left"><span>转弯方式</span></div></div>
            <a-radio-group v-model:value="flightControl.turnMode" style="margin-bottom:12px;">
              <a-radio value="auto">自动</a-radio>
              <a-radio value="waypoint">定点</a-radio>
            </a-radio-group>
            <div class="basicModelLR" v-if="flightControl.turnMode==='waypoint'">
              <div class="left"><span>悬停时间</span></div>
              <div><a-input style="width:80px;margin:0 5px;" v-model:value="flightControl.hoverTime" />s</div>
            </div>

            <div class="fc-form" style="margin-top:16px;">
              <div class="fc-row">
                <div class="fc-label">任务方式</div>
                <div class="fc-field">
                  <a-radio-group v-model:value="flightControl.missionMode" size="small">
                    <a-radio value="none">无任务</a-radio>
                    <a-radio value="photo">拍照</a-radio>
                  </a-radio-group>
                </div>
              </div>
              <template v-if="flightControl.missionMode==='photo'">
                <div class="fc-row">
                  <div class="fc-label">拍照方式</div>
                  <div class="fc-field">
                    <a-radio-group v-model:value="flightControl.photoMode" size="small">
                      <a-radio value="time">按时间</a-radio>
                      <a-radio value="distance">按距离</a-radio>
                    </a-radio-group>
                  </div>
                </div>
                <div class="fc-row" v-if="flightControl.photoMode==='time'">
                  <div class="fc-label">时间间隔</div>
                  <div class="fc-field">
                    <a-input style="width:120px" v-model:value="flightControl.timeInterval" />
                    <span>s</span>
                  </div>
                </div>
                <div class="fc-row" v-if="flightControl.photoMode==='distance'">
                  <div class="fc-label">距离间隔</div>
                  <div class="fc-field">
                    <a-input style="width:120px" v-model:value="flightControl.distanceInterval" />
                    <span>m</span>
                  </div>
                </div>
              </template>
            </div>

          </div>
        </div>
      </div>

      <div class="map-box">
        <GMap ref="RefChilde" @drawpoint="createWayPoint" />
        <div :class="showpointInfo? 'pointInfo basic-form-group-waypoint-show':'pointInfo basic-form-group-waypoint-hide'">
          <div class="partial-wayline-waypoint-header">
            <a-button size="small" @click="prevWaypoint">上一个</a-button>
            <div class="title"><span>{{wayLinePointName}}</span><a-button size="small" danger @click="detGraphicFlag=true">删除</a-button></div>
            <a-button size="small" @click="nextWaypoint">下一个</a-button>
            <span class="divider"></span>
            <a-button size="small" @click="showpointInfo=false">关闭</a-button>
          </div>
          <div class="basic-form-group-overview-items basic-form-group-overview-display" style="padding:16px;">
            <a-modal v-model:open="detGraphicFlag" title="提示">
              <template #footer>
                <a-button @click="detGraphicFlag=false">取消</a-button>
                <a-button type="primary" danger @click="sureDetGraphic()">删除</a-button>
              </template>
              <p>是否删除当前航线点?</p>
            </a-modal>

            <div class="ModelLRControl">
              <div class="takeoffPointPosition">
                <div class="position">
                  <div class="lon"><div class="label">经度</div><a-input v-model:value="pointLon" @change="resetQFD('MoveHXD')" /></div>
                  <div class="lat"><div class="label">纬度</div><a-input v-model:value="pointLat" @change="resetQFD('MoveHXD')" /></div>
                </div>
                <div class="controller">
                  <div class="solid-circle"></div>
                  <div class="item up" @click="positionUp('HXD')" @mousedown="startMoveQFD('up','HXD')" @mouseup="endMoveQFD()"><img src="../assets/images/Right Angle.png" alt=""></div>
                  <div class="item right" @click="positionRight('HXD')" @mousedown="startMoveQFD('right','HXD')" @mouseup="endMoveQFD()"><img src="../assets/images/Right Angle.png" alt=""></div>
                  <div class="item left" @click="positionLeft('HXD')" @mousedown="startMoveQFD('left','HXD')" @mouseup="endMoveQFD()"><img src="../assets/images/Right Angle.png" alt=""></div>
                  <div class="item down" @click="positionDown('HXD')" @mousedown="startMoveQFD('down','HXD')" @mouseup="endMoveQFD()"><img src="../assets/images/Right Angle.png" alt=""></div>
                </div>
              </div>
            </div>

            <div v-show="heightMode==='aboveGroundLevel'" style="width:100%;margin-top:16px;">
              <div class="label mb8"><div style="display:flex;justify-content:space-between;width:100%;"><span>相对地面高度</span><a-checkbox :checked="Placemark.useGlobalHeight=='1'" @change="changeUseGlobalHeight">跟随航线</a-checkbox></div></div>
              <div class="height_control mb16">
                <span :class="Placemark.height<=0||Placemark.useGlobalHeight=='1'?'disabled':''" @click="changeTakeOffRefPointH('PlacemarkHeight',-100)">-100</span>
                <span :class="Placemark.height<=0||Placemark.useGlobalHeight=='1'?'disabled':''" @click="changeTakeOffRefPointH('PlacemarkHeight',-10)">-10</span>
                <span :class="Placemark.height<=0||Placemark.useGlobalHeight=='1'?'disabled':''" @click="changeTakeOffRefPointH('PlacemarkHeight',-1)">-1</span>
                <a-input :disabled="Placemark.height<=0 || Placemark.height>=1500 || Placemark.useGlobalHeight=='1'" v-model:value="Placemark.height" />m
                <span :class="Placemark.height>=1500||Placemark.useGlobalHeight=='1'?'disabled':''" @click="changeTakeOffRefPointH('PlacemarkHeight',+1)">+1</span>
                <span :class="Placemark.height>=1500||Placemark.useGlobalHeight=='1'?'disabled':''" @click="changeTakeOffRefPointH('PlacemarkHeight',+10)">+10</span>
                <span :class="Placemark.height>=1500||Placemark.useGlobalHeight=='1'?'disabled':''" @click="changeTakeOffRefPointH('PlacemarkHeight',+100)">+100</span>
              </div>
            </div>

            <div class="basicModelLR mb8"><div class="left" style="display:flex;justify-content:space-between;width:100%;"><span>航点类型</span><a-checkbox :checked="Placemark.useGlobalTurnParam=='1'" @change="changeUseGlobalTurnParam">跟随航线</a-checkbox></div></div>
            <a-select v-model:value="globalWaypointTurnMode" style="width:328px;margin-bottom:16px;" :disabled="Placemark.useGlobalTurnParam=='1'" @change="changeSelectUseGlobalTurnParam">
              <a-select-option value="coordinateTurn">协调转弯</a-select-option>
              <a-select-option value="toPointAndStopWithDiscontinuityCurvature">直线飞行到点停</a-select-option>
              <a-select-option value="toPointAndStopWithContinuityCurvature">曲线飞行到点停</a-select-option>
              <a-select-option value="toPointAndPassWithContinuityCurvature">曲线飞行过点不停</a-select-option>
            </a-select>

            <div class="basicModelLR mb8"><div class="left" style="display:flex;justify-content:space-between;width:100%;"><span>飞行器偏航角模式</span><a-checkbox :checked="Placemark.useGlobalHeadingParam=='1'" @change="changeUseGlobalHeadingParam">跟随航线</a-checkbox></div></div>
            <a-select :value="Placemark.waypointHeadingParam && Placemark.waypointHeadingParam.waypointHeadingMode" style="width:328px;margin-bottom:16px;" popupClassName="gdmsSelect" :disabled="Placemark.useGlobalHeadingParam=='1'" @change="changeSelectUseGlobalHeadingParam">
              <a-select-option value="followWayline">沿航线方向</a-select-option>
              <a-select-option value="manually">手动控制</a-select-option>
              <a-select-option value="fixed">锁定当前偏航角</a-select-option>
              <a-select-option value="smoothTransition">均匀过渡至下一航点</a-select-option>
            </a-select>

            <div class="basicModelLR" style="margin-top:16px;width:100%;display:flex;justify-content:space-between;">
              <div class="left"><span>飞行速度</span></div>
              <div>
                <a-checkbox :checked="Placemark.useGlobalSpeed=='1'" @change="changeuseGlobalSpeed">跟随航线</a-checkbox>
                <a-input :disabled="Placemark.waypointSpeed<=1 || Placemark.waypointSpeed>=15 || Placemark.useGlobalSpeed=='1'" style="width:80px;margin:0 5px;" v-model:value="Placemark.waypointSpeed" />m/s
              </div>
            </div>
            <div class="speadSilder" style="width:100%;"><a-slider :disabled="Placemark.useGlobalSpeed=='1'" :value="Number(Placemark.waypointSpeed)" :min="1" :max="15" @update:value="onUpdateWaypointSpeed" /></div>

            <div class="basicModelLR" style="margin-top:16px;width:100%;display:flex;justify-content:space-between;">
              <div class="left"><span>云台俯仰角</span></div>
              <div><a-input :disabled="Placemark.gimbalPitchAngle<=-120 || Placemark.gimbalPitchAngle>=45" style="width:80px;margin:0 5px;" v-model:value="Placemark.gimbalPitchAngle" />°</div>
            </div>
            <div class="speadSilder" style="width:100%;"><a-slider :value="Number(Placemark.gimbalPitchAngle)" :min="-120" :max="45" @update:value="onUpdateGimbalPitch" /></div>

            <div class="basicModelLR mb8"><div class="left"><span>航点动作</span></div></div>
            <div class="action-group-header" @click="addActions = true"><span>添加动作</span><span>＋</span></div>

            <div class="action-group-list">
              <div v-for="(item) in Placemark.actionGroup" :key="item.actionGroupId">
                <draggable :list="item.action" handle=".mover" group="actionTriggerType" animation="300" @start="onStart" @end="onEnd">
                  <template #item="{ element }">
                    <div class="draggableItem" @click.stop="selectAction(item.actionGroupId,element.actionId)">
                      <div class="action-item-label">
                        <div class="action-item-prefix"><div class="mover">≡</div><span>{{ element.actionActuatorFunc }}</span></div>
                        <div class="action-item-suffix"><a-button size="small" @click.stop="delAction(item.actionGroupId,element.actionId)">删除</a-button></div>
                      </div>
                    </div>
                  </template>
                </draggable>
              </div>
            </div>

            <div class="add-action-panel waypoint-action-add" v-show="addActions">
              <div class="panel-header"><span class="panel-title">添加动作</span><span class="uranus-icon"><a-button size="small" @click="addActions=false">关闭</a-button></span></div>
              <div class="panel-section"><div class="payload-item-info">云台 I</div></div>
              <div class="panel-section panel-section-actions dark">
                <div class="panel-section-header">飞行器动作</div>
                <div @click="addAction('xt')" class="uranus-btn"><span>悬停</span><span>＋</span></div>
                <div @click="addAction('fxqphj')" class="uranus-btn"><span>飞行器偏航角</span><span>＋</span></div>
                <div class="panel-section-header">云台动作</div>
                <div @click="addAction('ytphj')" class="uranus-btn"><span>云台偏航角</span><span>＋</span></div>
                <div @click="addAction('ytfyj')" class="uranus-btn"><span>云台俯仰角</span><span>＋</span></div>
                <div class="panel-section-header">相机动作</div>
                <div @click="addAction('dxpz')" class="uranus-btn"><span>定向拍照</span><span>＋</span></div>
                <div @click="addAction('pz')" class="uranus-btn"><span>拍照</span><span>＋</span></div>
                <div @click="addAction('kslx')" class="uranus-btn"><span>开始录像</span><span>＋</span></div>
                <div @click="addAction('tzlx')" class="uranus-btn"><span>停止录像</span><span>＋</span></div>
                <div @click="addAction('xjbj')" class="uranus-btn"><span>相机变焦</span><span>＋</span></div>
                <div @click="addAction('cjwjj')" class="uranus-btn"><span>创建文件夹</span><span>＋</span></div>
                <div @click="addAction('multipleTiming')" class="uranus-btn"><span>开始等时间隔拍照</span><span>＋</span></div>
                <div @click="addAction('multipleDistance')" class="uranus-btn"><span>开始等距间隔拍照</span><span>＋</span></div>
                <div @click="addAction('end')" class="uranus-btn"><span>结束间隔拍照</span><span>＋</span></div>
              </div>
            </div>

          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.edit-wayLine{
  width: 100%;
  height: 100%;
  position: relative;
  .header-box {
    position: relative;
    display: flex;
    align-items: center;
    box-shadow: inset 0 -1px 0 0 #4f4f4f;
    justify-content: center;
    width: 100%;
    height: 48px;
    background-color: #232323;
    z-index: 9;
    color: #fff;
    .title-actions {
        position: absolute;
        left: 0;
        top: 0;
        padding-left: 16px;
        height: 100%;
        display: flex;
        align-items: center;
        img {
          cursor: pointer;
        }
    }
  }
  .editmain {
    width: 100%;
    height: calc(100% - 48px);
    position: relative;
    display: flex;
    flex: 1;
    overflow: hidden;
    .left-box {
      float: left;
      width: 360px;
      height: 100%;
      background-color: #232323;
    }
    .component-wayline-preset-info {
        margin-top: 16px;
        padding: 0 16px 16px;
        box-shadow: inset 0 -1px 0 0 #4f4f4f;
        display: flex;
        flex-direction: row;
        .name-and-device {
          display: flex;
          width: 0;
          flex: auto;
          flex-direction: column;
          background-color: #3c3c3c;
          border-radius: 2px;
          padding: 8px 10px;
          cursor: pointer;
          color: #fff;
        }
        .transform-wrapper {
          width: 22px;
          height: 64px;
          margin-left: 8px;
          background-color: #3c3c3c;
          border-radius: 2px;
          display: flex;
          align-items: center;
          justify-content: center;
          flex-shrink: 0;
          cursor: pointer;
          img {
            width: 20px;
            height: 20px;
          }
        }
      }
      .basic-form-group-overview-items{
        box-sizing: border-box;
        transition: opacity .35s;
        height: calc(100% - 81px);
        overflow: overlay;
        overflow-x: hidden;
        .item_box {
          padding: 8px 16px 12px;
          color: hsla(0,0%,100%,.45);
          display: flex;
          justify-content: space-between;
          flex-wrap: wrap;
          border-bottom: 1px solid #666;
          .option {
            width: 50%;
            margin-top: 4px;
          }
          .dgPointOut {
            margin-left: 5px;
            width: 14px;
            height: 14px;
          }
          .basicModelLR {
            width: 100%;
            display: flex;
            justify-content: space-between;
          }
          .basicModelLR {
            align-items: center;
            .left {
              display: inline-block;
              .dgCard {
                font-size: 12px;
              }
            }
            .right {
              display: inline-block;
              color: #2d8cf0;
              cursor: pointer;
              user-select: none;
              img {
                width: 20px;
                height: 20px;
              }
            }
          }
        }
        .qfd {
            .ModelLRControl {
              margin-top: 8px;
              width: 100%;
              padding: 12px;
              color: hsla(0,0%,100%,.45);
              background-color: #000;
              border: 1px solid #666;
              .height {
                .label {
                  margin-bottom: 6px;
                }
              }
            }
        }
      }
      .basic-form-group-overview-display,
      .basic-form-group-waypoint-display {
        display: flex;
        flex-direction: column;
      }
      .basic-form-group-overview-items,
      .basic-form-group-waypoint-items{
        box-sizing: border-box;
        padding: 16px 0;
        overflow: auto;
        overflow: overlay;
        overflow-x: hidden;
        .settings-list {
          margin-top: 12px;
          .check_box {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            color: #595959;
            font-size: 14px;
            font-variant: tabular-nums;
            line-height: 1.5715;
            list-style: none;
            font-feature-settings: normal;
            display: inline-block;
          }
        }
      }
    .map-box {
      position: relative;
      display: flex;
      flex: 1;
      justify-content: end;
      .pointInfo.basic-form-group-waypoint-hide {
        width: 0;
      }
      .pointInfo.basic-form-group-waypoint-show {
        width: 360px;
      }
      .pointInfo {
        transition: width .35s ease-in-out;
        z-index: 300;
        position: relative;
        background: #232323;
        display: flex;
        flex-flow: column;
        width: 360px;
        height: 100%;
        color: rgba(255, 255, 255, 0.45);
        .partial-wayline-waypoint-header{
          padding: 16px;
          display: flex;
          align-items: center;
          color: #fff;
          border-bottom: 1px solid #4f4f4f;
          width: 360px;
          img {
            width: 18px;
            height: 18px;
            cursor: pointer;
          }
          .title {
            flex: 1;
            display: flex;
            justify-content: center;
            align-items: center;
            span {
              margin-right: 5px;
            }
          }
        }
      }
      .add-action-panel {
        width: 240px;
        top: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
        background-color: #282828;
        color: #fff;
        font-size: 14px;
        line-height: 22px;
        box-shadow: 0 1px 4px 0 rgba(0,0,0,.5);
        .panel-header {
          padding: 16px;
          display: flex;
          align-items: center;
          .panel-title {
            font-weight: 600;
            flex: 1;
            color: #fff;
            font-size: 14px;
            line-height: 22px;
          }
          .uranus-icon img {
            width: 16px;
            height: 16px;
          }
        }
        .panel-section {
            border-top: 1px solid #4f4f4f;
            padding: 12px 16px;
            .payload-item-info {
              color: hsla(0,0%,100%,.45);
            }
        }
        .panel-section-actions {
            flex: auto;
            .panel-section-header{
              color: hsla(0,0%,100%,.45);
              margin-bottom: 8px;
            }
            .uranus-btn {
              position: relative;
              display: inline-flex;
              height: 32px;
              min-width: 96px;
              justify-content: center;
              align-items: center;
              border-radius: 2px;
              background: #3c3c3c;
              color: #fff;
              white-space: nowrap;
              text-align: center;
              transition: all .3s ease;
              touch-action: manipulation;
              -webkit-user-select: none;
              -moz-user-select: none;
              -ms-user-select: none;
              user-select: none;
              box-sizing: border-box;
              border: none;
              font-size: 14px;
              line-height: 22px;
              width: 100%;
              margin-left: 0;
              padding: 0 8px;
              margin-bottom: 8px;
              flex: 1;
              display: flex;
              justify-content: space-between;
              align-items: center;
              cursor: pointer;
              img {
                width: 16px;
                height: 16px;
                transform: rotate(45deg);
              }
            }
            .uranus-btn:hover {
                cursor: pointer;
                text-decoration: none!important;
                background: #5d5f61;
            }
        }
      }
      .waypoint-action-add {
        position: absolute;
        right: 100%;
      }
    }
  .fc-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  .fc-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
  }
  .fc-label {
    color: hsla(0,0%,100%,.45);
    min-width: 84px;
  }
  .fc-field {
    display: flex;
    align-items: center;
    gap: 8px;
    }
  }
  .height_control {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #fff;
    span {
      display: inline-block;
      padding: 0 5px;
      height: 22px;
      line-height: 22px;
      border-radius: 2px;
      background: #3c3c3c;
      text-align: center;
      transition: all .3s ease;
      box-sizing: border-box;
      font-size: 14px;
      cursor: pointer;
      user-select: none;
    }
    span:hover {
      cursor: pointer;
      text-decoration: none!important;
      background: #5d5f61;
    }
    input {
      padding: 2px 6px;
      width: 80px;
      margin: 0;
    }
  }
  .disabled {
    cursor: not-allowed!important;
    color: hsla(0,0%,100%,.25);
  }
  .disabled:hover {
    background: #3c3c3c !important;
  }
}

.divider {
    background: #4f4f4f;
    width: 1px;
    height: 19px;
    margin: auto 16px;
}
.takeoffPointPosition {
  display: flex;
  justify-content: space-between;
  .position {
    width: 178px;
    .label {
      color: hsla(0,0%,100%,.45);
      margin-bottom: 6px;
    }
  }
  .controller {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
    width: 120px;
    height: 120px;
    background-color: #3c3c3c;
    border-radius: 50%;
    position: relative;
    transform: rotate(45deg);
    cursor: pointer;
    overflow: hidden;
    user-select: none;
    .solid-circle {
        position: absolute;
        width: 23px;
        height: 23px;
        border-radius: 50%;
        background-color: #232323;
        transform: translateX(-50%) translateY(-50%);
        top: 50%;
        left: 50%;
        cursor: default;
    }
    .item {
      box-sizing: border-box;
      width: 60px;
      height: 60px;
      display: flex;
      justify-content: center;
      align-items: center;
      img {
        width: 20px;
      }
    }
    .item:hover {
        background-color: #5d5f61;
    }
    .up {
      border-right: 1px solid #4e4e4e;
        img {
        transform: rotate(-135deg) translateX(-5px);
      }
    }
    .right {
      border-bottom: 1px solid #4e4e4e;
        img {
        transform: rotate(-45deg) translateX(-5px);
      }
    }
    .down {
      border-left: 1px solid #4e4e4e;
        img {
        transform: rotate(45deg) translateX(-5px);
      }
    }
    .left {
      border-top: 1px solid #4e4e4e;
        img {
        transform: rotate(135deg) translateX(-5px);
      }
    }
  }
}
.content-wrapper {
  display: flex;
  align-items: center;
  height: 100px;
  position: relative;
  color: hsla(0, 0%, 100%, 0.404);
  .title-bottom {
      position: absolute;
      left: 24px;
      top: 38px;
      color: hsla(0,0%,100%,.45);
  }
  .absolute-height-lock {
    margin-right: 8px;
    display: flex;
    align-items: center;
    position: relative;
    top: 0;
    .uranus-icon {
        vertical-align: middle;
        position: relative;
        text-align: center;
        display: inline-flex;
        img {
          width: 16px;
          height: 16px;
        }
    }
  }
  .absolute-height-lock::before,
  .absolute-height-lock:after {
    content: "";
    display: block;
    width: 12px;
    height: 28px;
    position: absolute;
    border: 1px solid #4f4f4f;
    border-right: none;
    left: 50%;
  }
  .absolute-height-lock::before {
    top: 50%;
    transform: translateY(calc(-100% - 6px));
    border-bottom: none;
  }
  .absolute-height-lock:after {
    content: "";
    left: 50%;
    bottom: 50%;
    transform: translateY(calc(100% + 6px));
    border-top: none;
  }
  .absolute-height-slider{
    flex: 1;
    width: 304px;
    height: 100%;
    display: flex;
    flex-flow: column;
    justify-content: space-between;
  }
}
.hblabel {
  display: flex;
  width: 100%;
  justify-content: space-between;
  color: hsla(0,0%,100%,.45);
  font-size: 14px;
  line-height: 22px;
  align-items: center;
  margin: 8px 0;
  padding-left: 24px;
}
.action-group-header {
  background-color: #6d6d6d;
  font-size: 14px;
  line-height: 22px;
  padding: 5px 8px;
  display: flex;
  align-items: center;
  border-top-left-radius: 2px;
  border-top-right-radius: 2px;
  cursor: pointer;
  justify-content: space-between;
  img {
    width: 16px;
    height: 16px;
    transform: rotate(45deg);
  }
}
.action-group-header:hover {
    background: #5d5f61;
}
.component-wayline-yaw-mode-visual {
    display: flex;
    font-size: 12px;
    line-height: 14px;
    .left-container{
      width: 164px;
      height: 108px;
      position: relative;
      color: #fff;
      .image-tips {
          position: absolute;
      }
      .top {
          left: 0;
          top: 0;
          width: 100%;
          text-align: center;
      }
      .right {
        right: 10px;
        top: 50%;
        transform: translateY(-50%);
      }
      .bottom {
        left: 0;
        bottom: 0;
        width: 100%;
        text-align: center;
      }
      .left {
        left: 0;
        top: 50%;
        transform: translateY(-50%);
      }
      .position-center {
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translateX(-50%) translateY(-50%);
          width: 72px;
          height: 72px;
          border-radius: 50%;
          border: 1px solid #fff;
          background: #000;
          span {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translateX(-50%) translateY(-50%);
            display: block;
            width: 100%;
            height: 1px;
            background-color: #999;
          }
          .line-vertical {
            transform: translateX(-50%) translateY(-50%) rotate(90deg);
          }
      }
      .position-rotate-center {
          position: absolute;
          left: 50%;
          top: 50%;
          transform-origin: center;
          img {
            width: 32px;
            height: 32px;
          }
      }
      .position-rotate-circle {
        position: absolute;
        left: 50%;
        top: 18px;
        transform-origin: 0 36px;
        img {
          width: 9px;
          height: 9px;
          transform: rotate(-90deg);
          margin-left: -4px;
        }
      }
    }
    .right-container {
        flex: 1;
        color: hsla(0,0%,100%,.35);
        display: flex;
        flex-direction: column;
        justify-content: center;
        padding-left: 6px;
        .text-item {
          line-height: 20px;
          height: 20px;
          img {
            margin-right: 4px;
            width: 12px;
            height: 12px;
          }
        }
      }
}
.action-group-list {
    border: 1px solid #4f4f4f;
    background-color: #101010;
  .draggableItem {
    position: relative;
    margin: -1px;
    border: 1px solid #4f4f4f;
    padding: 8px 16px;
    cursor: pointer;
    background-color: #101010;
    .action-item-label {
      display: flex;
      align-items: center;
      color: hsla(0,0%,100%,.45);
      .action-item-prefix {
        display: flex;
        align-items: center;
        margin-right: 8px;
        flex: 1;
        width: 0;
        span {
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          width: 100%;
          display: inline-block;
        }
      }
      .action-item-suffix {
        display: flex;
        align-items: center;
        margin-left: 8px;
        img {
          width: 16px;
          height: 16px;
          margin-left: 8px;
        }
        .action-item-tag {
          font-size: 14px;
          line-height: 22px;
          color: hsla(0,0%,100%,.45);
          border: 1px solid hsla(0,0%,100%,.45);
          border-radius: 2px;
          padding: 0 4px;
          display: inline-block;
        }
      }
    }
    .mover img{
      width: 16px;
      height: 16px;
      margin-right: 8px;
    }
    .camera-select {
      display: flex;
      justify-content: space-between;
      margin-top: 8px;
    }
    .uranus-editable{
      height: 32px;
      display: flex;
      align-items: center;
      font-size: 14px;
      line-height: 22px;
      width: 100%;
      img {
        width: 16px;
        height: 16px;
        margin-left: 8px;
      }
    }
    .operations{
      border: 1px solid #4f4f4f;
      border-radius: 2px;
      .operation-attitude {
        padding-right: 5px;
        border-top: none !important;
      }
      .operation {
        padding: 8px;
        border-top: 1px solid #4f4f4f;
        .operation-title {
          display: flex;
          justify-content: space-between;
          color: hsla(0,0%,100%,.45);
        }
        .attitude-view {
          display: flex;
          align-items: center;
          .pitch-editor {
              padding-left: 7px;
              padding-right: 5px;
              position: relative;
              .pitch-bar {
                width: 7px;
                height: 111px;
                color: hsla(0,0%,100%,.2);
                background: currentcolor;
              }
              .marker{
                width: 7px;
                height: 2px;
                background-color: #fff;
                position: absolute;
                transform: translateY(-50%);
              }
              .marker.zero-marker {
                  width: auto;
                  right: 0;
                  left: 7px;
                  top: 50%;
              }
              .marker.limit-marker {
                  background-color: #e70102;
                  height: 1px;
                  transform: translateY(-100%);
              }
              .gimbal-icon {
                  position: absolute;
                  transform: rotate(90deg) translateX(-50%);
                  left: -1px;
                  font-size: 10px;
                  .gimbal-icon-inner {
                      margin: 0.5px 1px 1px;
                      display: block;
                      width: 1em;
                      height: 1em;
                      background-color: #1fa3f6;
                      position: relative;
                  }
                  .gimbal-icon-inner:before {
                      content: "";
                      display: block;
                      width: 0;
                      height: 0;
                      border-left: 0.5em solid transparent;
                      border-right: 0.5em solid transparent;
                      border-bottom: 0.5em solid #1fa3f6;
                      position: absolute;
                      bottom: 100%;
                  }
              }
              .gimbal-icon:before {
                  content: "";
                  display: block;
                  width: 0;
                  height: 0;
                  border-left: 0.5em solid transparent;
                  border-right: 0.5em solid transparent;
                  border-bottom: calc(0.5em + 1px) solid transparent;
                  position: absolute;
                  bottom: 100%;
              }
          }
          .yaw-editor{
            margin-left: 6px;
            flex-shrink: 0;
            position: relative;
            width: 94px;
            height: 94px;
            .yaw-limit {
                position: absolute;
                left: 0;
                top: 0;
                width: 100%;
                height: 100%;
                .limit-marker {
                    color: #e70102;
                    width: 16px;
                    height: 16px;
                    padding: 1px;
                    position: absolute;
                    top: 0;
                    display: flex;
                    justify-content: center;
                    left: calc(50% - 8px);
                    transform-origin: center 47px;
                }
                .limit-marker:before {
                    content: "";
                    display: block;
                    background-color: currentColor;
                    width: 1px;
                }
            }
          }

          .yaw-compass {
              position: relative;
              img {
                  width: 100%;
                  height: 100%;
              }
          }
          .yaw-drone {
              position: absolute;
              top: 50%;
              left: 50%;
              transform: translate(-50%,-50%);
              .uranus-icon {
                  vertical-align: middle;
                  position: relative;
                  text-align: center;
                  display: inline-flex;
                  img {
                    width: 36px;
                    height: 36px;
                  }
              }
          }
          .yaw-gimbal {
              position: absolute;
              left: 0;
              top: 0;
              width: 100%;
              height: 100%;
              display: flex;
              justify-content: center;
              padding: 5px;
              .gimbal-icon:before {
                  content: "";
                  display: block;
                  width: 0;
                  height: 0;
                  border-left: 0.5em solid transparent;
                  border-right: 0.5em solid transparent;
                  border-bottom: calc(0.5em + 1px) solid transparent;
                  position: absolute;
                  bottom: 100%;
              }
              .gimbal-icon-inner {
                  margin: 0.5px 1px 1px;
                  display: block;
                  width: 1em;
                  height: 1em;
                  background-color: #1fa3f6;
                  position: relative;
                  font-size: 8px;
              }
              .gimbal-icon-inner:before {
                  content: "";
                  display: block;
                  width: 0;
                  height: 0;
                  border-left: 0.5em solid transparent;
                  border-right: 0.5em solid transparent;
                  border-bottom: 0.5em solid #1fa3f6;
                  position: absolute;
                  bottom: 100%;
              }
          }
          .angle-sliders {
              display: flex;
              align-items: flex-start;
              flex: 1;
              .yaw-angle-lock {
                  display: flex;
                  align-items: center;
                  position: relative;
                  top: 14px;
                  height: 60px;
                  width: 32px;
                  right: 12px;
                  .lock-input {
                      width: 36px;
                      margin-right: 1px;
                      flex-shrink: 0;
                      box-sizing: border-box;
                      font-variant: tabular-nums;
                      list-style: none;
                      font-feature-settings: normal;
                      position: relative;
                      color: #595959;
                      font-size: 14px;
                      line-height: 1.5715;
                      background-color: #fff;
                      background-image: none;
                      transition: all .3s;
                      display: inline-block;
                      width: 90px;
                      margin: 0;
                      padding: 0;
                      border-radius: 2px;
                  }
              }
              .yaw-angle-lock:before,
              .yaw-angle-lock:after {
                  content: "";
                  display: block;
                  width: 18px;
                  height: 18px;
                  position: absolute;
                  border: 1px solid #4f4f4f;
                  border-right: none;
                  left: 70%;
              }
              .yaw-angle-lock:before{
                top: 0;
                border-bottom: none;
              }
              .yaw-angle-lock:after{
                bottom: 0;
                border-top: none;
              }
              .uranus-slider {
                  font-size: 12px;
                  line-height: 20px;
                  color: #fff;
                  .label-wrapper{
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    color: hsla(0,0%,100%,.45);
                    .prefix-wrapper {
                        overflow: hidden;
                        white-space: nowrap;
                        text-overflow: ellipsis;
                    }
                    .suffix-wrapper {
                      display: flex;
                      align-items: center;
                    }
                  }
                  .slider-wrapper {
                      display: flex;
                      align-items: center;
                      .uranus-icon {
                          vertical-align: middle;
                          position: relative;
                          text-align: center;
                          background: #3c3c3c;
                          width: 20px;
                          height: 20px;
                          line-height: 20px;
                          font-size: 18px;
                          user-select: none;
                      }
                      .wayline-app-ant-slider {
                        width: calc(100% - 40px);
                      }
                  }
              }
          }
        }
        .label-wrapper {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
      }
    }
  }
  .draggableItem:hover {
    cursor: pointer;
    background-color: #2c2c2c;
  }
  .selected {
    background-color: #4f4f4f;
  }
}

</style>
